Linux-C C语言使用cJSON开源库解析JSON数据

Linux-C C语言使用cJSON开源库解析JSON数据

一、简述

       记--在C语言中使用cJSON开源库解析JSON数据。

           例子1:读取简单的JSON数据

           例子2:读取JSON数据文件 

           例子3:读取JSON对象嵌套数据

           例子4:读取JSON数组数据

二、例子

cJSON第三方解析库:cJSON_x86.tar.gz

链接: https://pan.baidu.com/s/1jFhRZ8RDpMftlMKZU5M8_g 提取码: s7ib 

解压:tar -xjvf cJSON_x86.tar.bz2     //将cJSON_x86.tar.bz2解压到当前路径

例子1:读取简单的JSON数据

#include <stdio.h>
#include <stdlib.hs>
#include "cJSON.h"
 
int main(int argc, char* argv[])
{
	char buf[1024] = {" {\"date\":\"20181128\"} "};//要解析的json数据
 
	cJSON * root = cJSON_Parse(buf);//将字符串格式的json数据转化为JSON对象格式
	if(root == NULL)
	{
		printf("parse error\n");
		return -1;
	}
 
	cJSON *value = cJSON_GetObjectItem(root, "date");//根据键"date"获取其对应的值
	if(value == NULL)
	{
		printf("getvalue error\n");
		cJSON_Delete(root);
		return -1;
	}
 
	char *data = cJSON_Print(value);//将获取值转化为字符串格式
	if(data == NULL)
	{
		printf("printf error\n");
		cJSON_Delete(root);
		return -1;
	}
 
	printf("data=%s\n", data);//打印获取到的json数据
	free(data);
	
	//释放资源
	cJSON_Delete(root);	//json对象释放根节点,会自动释放子节点	
	
	return 0;
}
 

效果:编译命令:gcc json.c -o json -I ~/cJSON/include/cjson/ -L ~/cJSON/lib -lcjson

注:需要将cjson.so库放到环境变量:export LD_LIBRARY_PATH=/home/liang/cJSON/lib:$LD_LIBRARY_PATH

例子2:读取JSON数据文件 

data.json 数据文件

{
	"date": "29日星期四",
	"sunrise": "07:08",
	"high": "高温 9.0℃",
	"low": "低温 0.0℃",
	"sunset": "16:50",
	"aqi": 50.0,
	"fx": "东风",
	"fl": "4-5级",
	"type": "晴",
	"notice": "愿你拥有比阳光明媚的心情"
}

测试代码:

#include <stdio.h>
#include "cJSON.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
	//打开JSON数据文件 
	int fd = open("data.json",O_RDWR);
	if(fd < 0)
	{
		perror("open fail\n");
		return -1;
	}
		
	//读取文件中的数据 
	char buf[2048]={0};
	int ret = read(fd, buf, sizeof(buf));
	if(ret == -1)
	{
		perror("read error");
		return -1;
	}
	
	//关闭文件
	close(fd);
	
	//把该字符串数据转换成JSON对象
	cJSON *root=cJSON_Parse(buf);
	if(root == NULL)
	{
		printf("parse error\n");
		return -1;
	}
	
	//根据key值去获取对应的value 
	cJSON *value = cJSON_GetObjectItem(root,"date");
	if(value == NULL)
	{
	  printf("GetObjec error\n");
	  return -1;
	}
	
	//把数据转成 字符串输出  
	char  *data = cJSON_Print(value);
	printf("date=%s\n",data);
	free(data);
	data = NULL;
	
	value = cJSON_GetObjectItem(root,"fx");
	if(value == NULL)
	{
		printf("GetObjec error\n");
		cJSON_Delete(root);
		return -1;
	}
	
	//把数据转成 字符串输出  
	data = cJSON_Print(value);
	printf("notice=%s\n",data);
	free(data);
	data = NULL;

	
	//根据key值去获取对应的value 
	value = cJSON_GetObjectItem(root,"notice");
	if(value == NULL)
	{
		printf("GetObjec error\n");
		cJSON_Delete(root);
		return -1;
	}
	
	//把数据转成 字符串输出  
	data = cJSON_Print(value);
	printf("notice=%s\n",data);
	free(data);
	data = NULL;

	//释放资源
	cJSON_Delete(root);	//json对象释放根节点,会自动释放子节点	
	
	return 0;
}
 

效果:

例子3:读取JSON对象嵌套数据,获取键"quality"和键"notice"对应的数据。

JSON数据:

{
	"status": 200,
	"data": {
		"shidu": "35%",
		"pm25": 55.0,
		"pm10": 177.0,
		"quality": "轻度污染",
		"wendu": "4",
		"ganmao": "儿童、老年人及心脏、呼吸系统疾病患者人群应减少长时间或高强度户外锻炼",
		"yesterday": {
			"date": "27日星期二",
			"sunrise": "07:06",
			"high": "高温 10.0℃",
			"low": "低温 0.0℃",
			"sunset": "16:51",
			"aqi": 253.0,
			"fx": "南风",
			"fl": "<3级",
			"type": "晴",
			"notice": "愿你拥有比阳光明媚的心情"
		}
		
	}
}

代码:

#include <stdio.h>
#include "cJSON.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
	//打开保存JSON数据的文件 
	int fd = open("data.json",O_RDWR);
	if(fd < 0)
	{
		perror("open fail\n");
		return -1;
	}
		
	//读取文件中的数据 
	char buf[2048]={0};
	int ret = read(fd, buf, sizeof(buf));
	if(ret == -1)
	{
		perror("read error");
		return -1;
	}		
	
	//关闭文件
	close(fd);
	
	//把该字符串数据转换成JSON数据  (对象)
	cJSON *root=cJSON_Parse(buf);
	if(root == NULL)
	{
		printf("parse error\n");
		return -1;
	}
	
		  
	//取该对象中的value值 
	cJSON *value = cJSON_GetObjectItem(root,"data");//获取键"data"对应的JSON值
	if(value == NULL)
	{
		printf("GetObjec error\n");
		cJSON_Delete(root);
		return -1;
	}
		  
	cJSON *value2 = cJSON_GetObjectItem(value,"quality");//获取键"quality"对应的JSON值
	char *data = cJSON_Print(value2);
	printf("quality=%s\n", data);
	free(data);
	data = NULL;
	
	value = cJSON_GetObjectItem(value,"yesterday");//获取键"yesterday"对应的JSON值
	if(value == NULL)
	{
		printf("GetObjec error\n");
		cJSON_Delete(root);
		return -1;
	}
	
	value = cJSON_GetObjectItem(value,"notice"); //获取键"notice"对应的JSON值
	data = cJSON_Print(value);
	printf("notice=%s\n", data);
	free(data);
	data = NULL;
	
	//释放资源
	cJSON_Delete(root);
	
	return 0;
}

效果:

例子4:读取JSON数组数据

JSON数据:

{
	    "time": "2018-11-28 09:06:12",
		"forecast": [{
			"date": "28日星期三",
			"sunrise": "07:07",
			"high": "高温 11.0℃",
			"low": "低温 1.0℃",
			"sunset": "16:50",
			"aqi": 116.0,
			"fx": "东风",
			"fl": "<3级",
			"type": "多云",
			"notice": "阴晴之间,谨防紫外线侵扰"
		}, {
			"date": "29日星期四",
			"sunrise": "07:08",
			"high": "高温 9.0℃",
			"low": "低温 0.0℃",
			"sunset": "16:50",
			"aqi": 50.0,
			"fx": "东风",
			"fl": "4-5级",
			"type": "晴",
			"notice": "愿你拥有比阳光明媚的心情"
		}, {
			"date": "30日星期五",
			"sunrise": "07:09",
			"high": "高温 11.0℃",
			"low": "低温 0.0℃",
			"sunset": "16:50",
			"aqi": 89.0,
			"fx": "西风",
			"fl": "3-4级",
			"type": "晴",
			"notice": "愿你拥有比阳光明媚的心情2"
		}, {
			"date": "01日星期六",
			"sunrise": "07:10",
			"high": "高温 12.0℃",
			"low": "低温 3.0℃",
			"sunset": "16:49",
			"aqi": 106.0,
			"fx": "东南风",
			"fl": "<3级",
			"type": "晴",
			"notice": "愿你拥有比阳光明媚的心情3"
		}, {
			"date": "02日星期日",
			"sunrise": "07:11",
			"high": "高温 10.0℃",
			"low": "低温 2.0℃",
			"sunset": "16:49",
			"aqi": 174.0,
			"fx": "南风",
			"fl": "3-4级",
			"type": "阴",
			"notice": "不要被阴云遮挡住好心情"
		}]
	
}

测试代码:

#include <stdio.h>
#include "cJSON.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
	//打开保存JSON数据的文件 
	int fd = open("data.json",O_RDWR);
	if(fd < 0)
	{
		perror("open fail\n");
		return -1;
	}
		
	//读取文件中的数据 
	char buf[2048] = {0};
	int ret = read(fd, buf, sizeof(buf));
	if(ret == -1)
	{
		perror("read error");
		return -1;
	}
	
	//关闭文件
	close(fd);
	
	//把该字符串数据转换成JSON数据  (对象)
	cJSON *root=cJSON_Parse(buf);
	if(root == NULL)
	{
		printf("parse error\n");
		return -1;
	}
	
	//根据key值去获取对应的value 
	cJSON *value = cJSON_GetObjectItem(root,"time");
	if(value == NULL)
	{
		printf("GetObjectItem error\n");
		cJSON_Delete(root);
		return -1;
	}
	//把数据转成 字符串输出  
	char* data = cJSON_Print(value);
	printf("time=%s\n",data);
	free(data);
	data = NULL;
	
	//获取数组对象 
	//当前的value 是一个数组对象
	value = cJSON_GetObjectItem(root,"forecast");
	if(value == NULL)
	{
		printf("GetObjectItem error\n");
		cJSON_Delete(root);
		return -1;
	}
	
	//获取该数组对象的大小
	int len = cJSON_GetArraySize(value);
	printf("元素个数len=%d\n",len);
	
	//根据下标获取对象   取出第0项
	int i = 0;
	char* val = NULL;
	cJSON * type_value = NULL;
	cJSON * date_value = NULL;
	
	for(i=0;i<len;i++)
	{
		
		date_value = cJSON_GetArrayItem(value,i);
		type_value = cJSON_GetArrayItem(value,i);
		
		//获取KEY对应的value 
		date_value = cJSON_GetObjectItem(date_value,"date");
		type_value = cJSON_GetObjectItem(type_value,"type");
		
		if(date_value == NULL || type_value == NULL)
		{
			printf("GetObjectItem error\n");
			cJSON_Delete(root);
			return -1;
		}
		
		//获取完毕后转换打印  
		data = cJSON_Print(date_value);
		val = cJSON_Print(type_value);
		printf("%s\t%s\n", data, val);
		free(data);
		free(val);
		
	}
	cJSON_Delete(root);
	
	return -1;
	
}

效果:

三、总结

3.1 使用完JSON对象后需要释放,释放跟节点即可。

//json对象释放根节点,会自动释放子节点
cJSON * root = cJSON_Parse(buf);
cJSON_Delete(root);    

 

3.2 cJSON_Print(), print_number(), parse_string()返回值非空时是一个堆空间地址,使用完需要释放, 一个cJSON_Print对应一个free。

cJSON *json;
json = cJSON_Parse(buf);
if (NULL != json) {
	char *out = cJSON_Print(json);
	
	if (NULL != out) {
		printf("%s\n",out);
		free(out);
	}
	
	cJSON_Delete(json);
}

例如:结果是数字类型

cJSON_Print() --》print_value() --》print_number() --》cJSON_malloc() --》malloc()

 

 

 

    

 

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值