全面详解C语言使用cJSON解析JSON字符

cJSON对象的实现采用了树形结构,每个对象是树的一个节点,每个节点由cJSON这个结构体组成,对象中的元素也由cJSON这个结构体组成。同一层的对象和元素是双向链表结构,由next和prev指针链接。不同层的对象或元素由child指针链接起来。type表示对象或元素类型,string表示对象或节点的名称。元素的值存储在valuestring,  valueint和valuedouble中。cJSON.h中有详细的注释

为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件!

如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更好!

且文件体积大小不到30k,源代码思路也非常清晰,也非常适合研究。

点击下载CJSON

typedef struct cJSON 
{     //cJSON结构体
       struct cJSON *next,*prev;               /* 遍历数组或对象链的前向或后向链表指针*/
       struct cJSON *child;                   /* 数组或对象的孩子节点*/
       int type;                              /* key的类型*/
       char *valuestring;                     /* 字符串值*/
       int valueint;                          /* 整数值*/
       double valuedouble;                    /* 浮点数值*/
       char *string;                          /* key的名字*/
} cJSON;

正所谓万丈高楼平地起,先从最简单的开始!

先来介绍四个常用的cJSON函数:

cJSON *cJSON_Parse(const char *value);

作用:将一个JSON数据包,按照cJSON结构体的结构序列化整个数据包,并在堆中开辟一块内存存储cJSON结构体
返回值:成功返回一个指向内存块中的cJSON的指针,失败返回NULL

 

cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);

作用:获取JSON字符串字段值
返回值:成功返回一个指向cJSON类型的结构体指针,失败返回NULL

 

char  *cJSON_Print(cJSON *item);

作用:将cJSON数据解析成JSON字符串,并在堆中开辟一块char*的内存空间存储JSON字符串
返回值:成功返回一个char*指针该指针指向位于堆中JSON字符串,失败返回NULL

 

void  cJSON_Delete(cJSON *c);

作用:释放位于堆中cJSON结构体内存
返回值:无

 

假如说有这样的一个JSON字符串

{
 "test_1":"0"
 "test_2":"1"
 "test_3":"2"
} //json_string

这是最简单的JSON字符串

我们首先要先将这个字符串打包成cJSON数据格式

cJSON* cjson = cJSON_Parse(json_string);

打包后使用if语句或三目表达式判断一下是否将JSON字符串打包成cJSON数据格式

if(cjson == NULL)
{
    printf("json pack into cjson error...");
}
else
{//打包成功调用cJSON_Print打印输出
    printf("%s\r\n",cJSON_Print(cjson));
}
然后依次获取json字符串中的每个字段的值并打印输出
//cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型!
char* test_1_string = cJSON_GetObjectltem(cjson,"test_1")->valuestring;
char* test_2_string = cJSON_GetObjectltem(cjson,"test_2")->valuestring;
char* test_3_string = cJSON_GetObjectltem(cjson,"test_3")->valuestring;
//打印输出
printf("%s",*test_1_string);
printf("%s",*test_2_string);
printf("%s",*test_3_string);

最后别忘记释放内存

//delete cjson
cJSON_Delete(cjson);

 完整代码:

#include <stdio.h>
#include "cJSON.h"

int main()
{
	char json_string[] ="{	\"cmd\":12,				\
	 						\"device\":\"lamp\",	\
	 						\"power\":1,			\
	 						\"brightness\":50		\
	 					}";									
	 //JSON字符串到cJSON格式
	cJSON* cjson = cJSON_Parse(json_string); 
	//判断cJSON_Parse函数返回值确定是否打包成功
	if(cjson == NULL)
	{
	printf("json pack into cjson error...");
	}
	else
	{//打包成功调用cJSON_Print打印输出
	    printf("%s\r\n",cJSON_Print(cjson));
	}
 
	//获取字段值
	//cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型!
	int test_1_string = cJSON_GetObjectItem(cjson,"cmd")->valueint;
	char* test_2_string = cJSON_GetObjectItem(cjson,"device")->valuestring;
	int test_3_string = cJSON_GetObjectItem(cjson,"power")->valueint;
	int test_4_string = cJSON_GetObjectItem(cjson,"brightness")->valueint;
 
	//打印输出
	printf("%d\r\n",test_1_string);
	printf("%s\r\n",test_2_string);
	printf("%d\r\n",test_3_string);
	printf("%d\r\n",test_4_string);
	 
	//delete cjson
	cJSON_Delete(cjson);
}

是不是很easy?下面来教大家如何使用cJSON解析数组!

{
     "test_arr":[{
    {
      "test_1":"arr_1",
      "test_2":"arr_2",
      "test_3":"arr_3"
    },
    {
     "test_1":"1",
     "test_2":"2",
     "test_3":"3"
    }
    }]
}

在开始前介绍一个函数

int cJSON_GetArraySize(cJSON *array);

作用:获取数组成员对象个数
返回值:数组成员对象个数


首先第一步打包

cJSON* cjson = cJSON_Parse(json_arr_string);

第二步判断打包是否成功

if(cjson == NULL)
{
    printf("cjson error...");
}
else
{//打包成功调用cJSON_Print打印输出
    printf("%s\r\n",cJSON_Print(cjson));
}

第三步获取数组对象

cJSON* test_arr = cJSON_GetObjectltem(cjson,"test_arr");

第四步获取数组对象个数便于循环

int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2

第五步获取test_arr数组对象孩子节点

cJSON* arr_item = test_arr->child;//子对象

第六步循环获取数组下每个字段的值并使用cJSON_Print打印: 

for(int i = 0;i <=(arr_size-1)/*0*/;++i)
{
	printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_1")));
	printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_2")));
	printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_3")));
	arr_item = arr_item->next;//下一个子对象

}

 

最后别忘记释放

cJSON_Delete(cjson);

完整代码:

#include <stdio.h>
#include "cJSON.h"

int main()
{


char json_arr_string[]="{\"test_arr\":[{\"test_1\":\"arr_1\",\"test_2\":\"arr_2\",\"test_3\":\"arr_3\"},{\"test_1\":\"1\",\"test_2\":\"2\",\"test_3\":\"3\"}]}";	


	cJSON* cjson = cJSON_Parse(json_arr_string);
	if(cjson == NULL)
	{
		printf("cjson error...\r\n");
	}
	else
	{//打包成功调用cJSON_Print打印输出
		printf("%s\r\n",cJSON_Print(cjson));
	}
	cJSON* test_arr = cJSON_GetObjectItem(cjson,"test_arr");
	int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2
	cJSON* arr_item = test_arr->child;//子对象

	for(int i = 0;i <=(arr_size-1)/*0*/;++i)
	{
		printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_1")));
		printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_2")));
		printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_3")));
		arr_item = arr_item->next;//下一个子对象
	}
	cJSON_Delete(cjson);


}

 

  • 25
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值