全面详解C语言使用cJSON解析JSON字符[转载]
cJSON对象的实现采用了树形结构,每个对象是树的一个节点,每个节点由cJSON这个结构体组成,对象中的元素也由cJSON这个结构体组成。同一层的对象和元素是双向链表结构,由next和prev指针链接。不同层的对象或元素由child指针链接起来。type表示对象或元素类型,string表示对象或节点的名称。元素的值存储在valuestring, valueint和valuedouble中。cJSON.h中有详细的注释
为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件!
如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更好!
且文件体积大小不到30k,源代码思路也非常清晰,也非常适合研究。
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