ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

全面详解C语言使用cJSON解析JSON字符[转载]

2021-04-26 14:02:16  阅读:308  来源: 互联网

标签:arr string cJSON C语言 cjson JSON printf test


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

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

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

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

点击下载CJSON

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

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

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

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

 1 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); 
作用:获取JSON字符串字段值
返回值:成功返回一个指向cJSON类型的结构体指针,失败返回NULL

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

 1 void cJSON_Delete(cJSON *c); 
作用:释放位于堆中cJSON结构体内存
返回值:无
 

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

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

这是最简单的JSON字符串

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

 1 cJSON* cjson = cJSON_Parse(json_string); 
打包后使用if语句或三目表达式判断一下是否将JSON字符串打包成cJSON数据格式

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

最后别忘记释放内存

 1 //delete cjson 2 cJSON_Delete(cjson);  
 完整代码:

 1 #include <stdio.h>
 2 #include "cJSON.h"
 3 
 4 int main()
 5 {
 6 char json_string[] ="{    \"cmd\":12,    \
 7 \"device\":\"lamp\",    \
 8 \"power\":1,    \
 9 \"brightness\":50    \
10 }";    
11 //JSON字符串到cJSON格式
12 cJSON* cjson = cJSON_Parse(json_string); 
13 //判断cJSON_Parse函数返回值确定是否打包成功
14 if(cjson == NULL)
15 {
16 printf("json pack into cjson error...");
17 }
18 else
19 {//打包成功调用cJSON_Print打印输出
20 printf("%s\r\n",cJSON_Print(cjson));
21 }
22 
23 //获取字段值
24 //cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型!
25 int test_1_string = cJSON_GetObjectItem(cjson,"cmd")->valueint;
26 char* test_2_string = cJSON_GetObjectItem(cjson,"device")->valuestring;
27 int test_3_string = cJSON_GetObjectItem(cjson,"power")->valueint;
28 int test_4_string = cJSON_GetObjectItem(cjson,"brightness")->valueint;
29 
30 //打印输出
31 printf("%d\r\n",test_1_string);
32 printf("%s\r\n",test_2_string);
33 printf("%d\r\n",test_3_string);
34 printf("%d\r\n",test_4_string);
35 
36 //delete cjson
37 cJSON_Delete(cjson);
38 }
39 是不是很easy?下面来教大家如何使用cJSON解析数组!
40 
41 {
42 "test_arr":[{
43 {
44 "test_1":"arr_1",
45 "test_2":"arr_2",
46 "test_3":"arr_3"
47 },
48 {
49 "test_1":"1",
50 "test_2":"2",
51 "test_3":"3"
52 }
53 }]
54 }

在开始前介绍一个函数

 1 int cJSON_GetArraySize(cJSON *array); 
作用:获取数组成员对象个数
返回值:数组成员对象个数

首先第一步打包

 1 cJSON* cjson = cJSON_Parse(json_arr_string); 
第二步判断打包是否成功

1 if(cjson == NULL)
2 {
3 printf("cjson error...");
4 }
5 else
6 {//打包成功调用cJSON_Print打印输出
7 printf("%s\r\n",cJSON_Print(cjson));
8 }

第三步获取数组对象

 1 cJSON* test_arr = cJSON_GetObjectltem(cjson,"test_arr"); 
第四步获取数组对象个数便于循环

 1 int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2 
第五步获取test_arr数组对象孩子节点

 1 cJSON* arr_item = test_arr->child;//子对象 
第六步循环获取数组下每个字段的值并使用cJSON_Print打印: 

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

最后别忘记释放

 1 cJSON_Delete(cjson); 
完整代码:

 1 #include <stdio.h>
 2 #include "cJSON.h"
 3 
 4 int main()
 5 {
 6 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\"}]}";    
 7 
 8 cJSON* cjson = cJSON_Parse(json_arr_string);
 9 if(cjson == NULL)
10 {
11 printf("cjson error...\r\n");
12 }
13 else
14 {//打包成功调用cJSON_Print打印输出
15 printf("%s\r\n",cJSON_Print(cjson));
16 }
17 cJSON* test_arr = cJSON_GetObjectItem(cjson,"test_arr");
18 int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2
19 cJSON* arr_item = test_arr->child;//子对象
20 
21 for(int i = 0;i <=(arr_size-1)/*0*/;++i)
22 {
23 printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_1")));
24 printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_2")));
25 printf("%s\r\n",cJSON_Print(cJSON_GetObjectItem(arr_item,"test_3")));
26 arr_item = arr_item->next;//下一个子对象
27 }
28 cJSON_Delete(cjson);
29 }

————————————————
版权声明:本文为CSDN博主「void*_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36612961/article/details/90768404

标签:arr,string,cJSON,C语言,cjson,JSON,printf,test
来源: https://www.cnblogs.com/seanhn/p/14704329.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有