當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
cJSON 使用笔记
生活随笔
收集整理的這篇文章主要介紹了
cJSON 使用笔记
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近在stm32f103上做一個智能家居的項目,其中選擇的實時操作系統是 rt_thread OS v1.2.2穩定版本,其中涉及到C和java(android)端數據的交換問題,經過討論和研究,選擇了json格式的數據進行交互。當然,如果自己去寫一個json解析器,有點重造輪子的嫌疑。于是使用了開源的json解析器。考慮到是嵌入式平臺,在一位朋友的推薦下,選擇了輕量級別的cJSON。
??????????????????????????????????????????????????????????????????????????????????????????????????????? 使????? 用??????????????????????????????????????????????????????????????????????????????????????????????????? ?
?????? cJSON 開源項目位置:? http://sourceforge.net/projects/cjson/
?????? cJSON,目前來說,就只有兩個文件,一個cJSON.c 一個cJSON.h文件。使用的時候,自己創建好一個main.c文件后,如果是在linux pc上,請使用以下命令進行編譯:
?
1 gcc -g -Wall *.c -l m
就會默認生成一個 a.out文件,執行即可。在linux下編譯的時候,注意鏈接 libm 庫。
?????? 整個項目都是以極標準的C來寫的,意思說,可以跨各種平臺使用了。不過,還是有兩三處需要微調一下<針對stm32f103? + rt_thread >。其中修改一下malloc & free & size_t 這三個東西:
?46 static void *(*cJSON_malloc)(size_t sz) = malloc;
?47 static void (*cJSON_free)(void *ptr) = free;
----------------------------------------
?46 static void *(*cJSON_malloc)(size_t sz) = rt_malloc;
?47 static void (*cJSON_free)(void *ptr) = rt_free;
復制代碼
?60 void cJSON_InitHooks(cJSON_Hooks* hooks)
?61 {
?62???? if (!hooks) { /* Reset hooks */
?63???????? cJSON_malloc = malloc;
?64???????? cJSON_free = free;
?65???????? return;
?66???? }
?67
?68???? cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
?69???? cJSON_free?? = (hooks->free_fn)?hooks->free_fn:free;
?70 }
----------------------------------------------------
?60 void cJSON_InitHooks(cJSON_Hooks* hooks)
?61 {
?62???? if (!hooks) { /* Reset hooks */
?63???????? cJSON_malloc = rt_malloc;
?64???????? cJSON_free = rt_free;
?65???????? return;
?66???? }
?67
?68???? cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:rt_malloc;
?69???? cJSON_free?? = (hooks->free_fn)?hooks->free_fn:rt_free;
?70 }
復制代碼
free & malloc就這么兩個地方要修改一下吧,其中size_t 這個應該是在 .h 文件修改,主要是rtt的 rt_malloc 和這里的malloc使用的不同,所以修改了下---不一定非要修改。
所以,這東西說實話,也不存在什么移植不移植的問題了。很輕松的就可以在各個平臺使用了。
?????????????????????????????????????????????????????????????????????????????????????????????????? 例?????? 程???????????????????????????????????????????????????????????????????????????????????????????????????????? ?
????? 不對json的格式進行說明了,下面直接記下使用方法了。
????? 第一,創建json數據串。這數據串,可能是對象,也可能是數組,也可能是它們的各種組合,其中再加上一些鍵值對。有一點要先說明:它們的組合,符合父子繼承格式--這也是json數據串的特點。
???? <1>? 創建一個對象,并在這個對象里面添加一個字符串鍵值和一個數字鍵值:
復制代碼
?1 int create_js(void)
?2 {
?3???? cJSON *root;
?4???? /*create json string root*/
?5???? root = cJSON_CreateObject();
?6???? if(!root) {
?7???????? DEBUG("get root faild !\n");
?8???????? goto EXIT;
?9???? }else DEBUG("get root success!\n");
10
11???? {
12???????? cJSON * js_body ;
13
14???????? const char *const body = "body";
15???????? cJSON_AddItemToObject(root, body, js_body=cJSON_CreateObject());
16???????? cJSON_AddStringToObject(js_body,"name","xiaohui");
17???????? cJSON_AddNumberToObject(js_body,"value",600);
18???????? {
19???????? char *s = cJSON_PrintUnformatted(root);
20???????? if(s){
21???????????? DEBUG("create js string is %s\n",s);
22???????????? free(s);
23???????? }
24???????? }
25???????? cJSON_Delete(root);
26???? }
27
28???? return 0;
29 EXIT:
30???? return -1;
31 }
32
33 int main(int argc, char **argv)
34 {
35???? create_js();
36???? return 0;
37 }
復制代碼
運行結果:
1 create js string is? {"body":{"name":"xiaohui","value":600}}
說明: 創建根對象,使用? cJSON_CreateObject(); 這個API,返回的是一個 cJSON的指針,注意,在這個指針用完了以后,需要手工調用 cJSON_Delete(root); 進行內存回收。
創建body對象的時候,是在根對象的基礎上進行創建,而插入name 和value的時候,是以body為父節點。需要注意的是? json 格式的數據,雖然也是一個字符串的樣子,但這個時候還是無法當成普通的字符串進行使用,需要調用 cJSON_PrintUnformatted(root) 或者 cJSON_Print(root);來將json對象轉換成普通的字符串,并且都是以該json對象的根為基點。兩個API的區別即是:一個是沒有格式的:也就是轉換出的字符串中間不會有"\n" "\t"之類的東西存在,而cJSON_Print(root);打印出來是人看起來很舒服的格式。僅此而已。
<2> 創建一個數組,并向數組添加一個字符串和一個數字:
復制代碼
?1 int create_js(void)
?2 {
?3???? cJSON *root, *js_body;
?4???? root = cJSON_CreateArray();
?5???? cJSON_AddItemToArray(root, cJSON_CreateString("Hello world"));
?6???? cJSON_AddItemToArray(root, cJSON_CreateNumber(10));
?7???? {
?8 //??????? char *s = cJSON_Print(root);
?9???????? char *s = cJSON_PrintUnformatted(root);
10???????? if(s){
11???????????? DEBUG(" %s \n",s);
12???????????? free(s);
13???????? }
14???? }
15???? if(root)
16???? cJSON_Delete(root);
17
18???? return 0;
19 EXIT:
20???? return -1;
21 }
22
23 int main(int argc, char **argv)
24 {
25???? create_js();
26???? return 0;
27 }
復制代碼
運行結果:
1 ["Hello world",10]
<3> 對象里面包括一個數組,數組里面包括對象,對象里面再添加一個字符串和一個數字:
復制代碼
?1 int create_js(void)
?2 {
?3???? cJSON *root, *js_body, *js_list;
?4???? root = cJSON_CreateObject();
?5???? cJSON_AddItemToObject(root,"body", js_body = cJSON_CreateArray());
?6???? cJSON_AddItemToArray(js_body, js_list = cJSON_CreateObject());
?7???? cJSON_AddStringToObject(js_list,"name","xiaohui");
?8???? cJSON_AddNumberToObject(js_list,"status",100);
?9
10???? {
11???????? //??????? char *s = cJSON_Print(root);
12???????? char *s = cJSON_PrintUnformatted(root);
13???????? if(s){
14???????????? DEBUG(" %s \n",s);
15???????????? free(s);
16???????? }
17???? }
18???? if(root)
19???????? cJSON_Delete(root);
20
21???? return 0;
22 EXIT:
23???? return -1;
24 }
25
26 int main(int argc, char **argv)
27 {
28???? create_js();
29???? return 0;
30 }
復制代碼
運行結果:
1 {"body":[{"name":"xiaohui","status":100}]}
<4>其他組合就依次類推,只要搞清楚父子關系即可。隨便嵌套隨便玩。不再貼了。
?? <第二, 解析json數據串>
?? 步驟: 1? 先將普通的json 字符串 處理成 json對象格式。 2? 根據關鍵字進行解析,解析的時候,需要根據關鍵字值的類型進行判斷,而這些類型,已經在cJSON.h里面寫明白了,包括:對象、數組、普通字符串、普通變量等等。
?? <偷個懶吧,將自己學習的時候用的資料現貼過來,后面休息一下再詳細補充自己在工程中的解析方法>
http://blog.csdn.net/xukai871105/article/details/17094113
http://blog.sina.com.cn/s/blog_a6fb6cc90101ffme.html
?
<當然,他寫的比較簡潔,還有些可以補充的---其實我已經在上面使用文字進行補充過了。當然,不同的工程,可能解析的方法和側重點并不相同>
?
?
或許,是時候把解析的部分補充上來了:
處理流程:
1, 先將普通的json串處理成json對象,也就是所謂的創建json root的過程,只有一行代碼即可:
cJSON *root;
root = cJSON_Parse(js_string);
ps:需要注意的是,這個root在解析完成后,需要釋放掉,代碼如下:
if (root)
? cJSON_Delete(root);
2,開始拿關鍵字,但如果關鍵字還有父層或者祖層,那就需要先從父層開拿,所謂剝洋蔥是也!
先說沒有父層的:
{"name":"xiaohong","age":10}
這個字符串這樣拿即可:
復制代碼
?1 char *s = "{\"name\":\"xiao hong\",\"age\":10}";
?2 cJSON *root = cJSON_Parse(s);
?3 if(!root) {
?4???? printf("get root faild !\n");
?5???? return -1;
?6 }
?7 cJSON *name = cJSON_GetObjectItem(root, "name");
?8 if(!name) {
?9???? printf("No name !\n");
10???? return -1;
11 }
12 printf("name type is %d\n",name->type);
13 printf("name is %s\n",name->valuestring);
14
15 cJSON *age = cJSON_GetObjectItem(root, "age");
16 if(!age) {
17???? printf("no age!\n");
18???? return -1;
19 }
20 printf("age type is %d\n", age->type);
21 printf("age is %d\n",age->valueint);
復制代碼
顯示結果:
1 name type is 4
2 name is xiao hong
3 age type is 3
4 age is 10
需要注意的是: 上面的type 已經在cJSON.h里面定義好了,有自己的意義。如果是在嚴格的場所,應該先判定該 item的type,然后再考慮去拿值。
而如果有父層的話,無非就是接著向下拿就是了,稍微修改下前面的demo吧:
處理這串數據吧:
{\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}
復制代碼
?1 char *s = "{\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}";
?2 cJSON *root = cJSON_Parse(s);
?3 if(!root) {
?4???? printf("get root faild !\n");
?5???? return -1;
?6 }
?7
?8 cJSON *js_list = cJSON_GetObjectItem(root, "list");
?9 if(!js_list) {
10???? printf("no list!\n");
11???? return -1;
12 }
13 printf("list type is %d\n",js_list->type);
14
15 cJSON *name = cJSON_GetObjectItem(js_list, "name");
16 if(!name) {
17???? printf("No name !\n");
18???? return -1;
19 }
20 printf("name type is %d\n",name->type);
21 printf("name is %s\n",name->valuestring);
22
23 cJSON *age = cJSON_GetObjectItem(js_list, "age");
24 if(!age) {
25???? printf("no age!\n");
26???? return -1;
27 }
28 printf("age type is %d\n", age->type);
29 printf("age is %d\n",age->valueint);
30
31 cJSON *js_other = cJSON_GetObjectItem(root, "other");
32 if(!js_other) {
33???? printf("no list!\n");
34???? return -1;
35 }
36 printf("list type is %d\n",js_other->type);
37
38 cJSON *js_name = cJSON_GetObjectItem(js_other, "name");
39 if(!js_name) {
40???? printf("No name !\n");
41???? return -1;
42 }
43 printf("name type is %d\n",js_name->type);
44 printf("name is %s\n",js_name->valuestring);
45
46 if(root)
47???? cJSON_Delete(root);
48???? return 0;
復制代碼
打印結果:
復制代碼
1 list type is 6
2 name type is 4
3 name is xiao hong
4 age type is 3
5 age is 10
6 list type is 6
7 name type is 4
8 name is hua hua
復制代碼
所謂子子孫孫無窮盡也,按照上面那個方法推下去即可。
3,json 里數組怎么取?
1 {\"list\":[\"name1\",\"name2\"]}
代碼如下:
復制代碼
?1 int main(int argc, char **argv)
?2 {
?3 char *s = "{\"list\":[\"name1\",\"name2\"]}";
?4 cJSON *root = cJSON_Parse(s);
?5 if(!root) {
?6???? printf("get root faild !\n");
?7???? return -1;
?8 }
?9 cJSON *js_list = cJSON_GetObjectItem(root, "list");
10 if(!js_list){
11???? printf("no list!\n");
12???? return -1;
13 }
14 int array_size = cJSON_GetArraySize(js_list);
15 printf("array size is %d\n",array_size);
16 int i = 0;
17 cJSON *item;
18 for(i=0; i< array_size; i++) {
19???? item = cJSON_GetArrayItem(js_list, i);
20???? printf("item type is %d\n",item->type);
21???? printf("%s\n",item->valuestring);
22 }
23
24 if(root)
25???? cJSON_Delete(root);
26???? return 0;
27 }
復制代碼
對頭,好簡單的樣子<在別人的庫上使用>
?
4? 如果json數組里面又搞了對象怎么辦?
不怕搞對象,就怕這樣搞對象? 無他,就是稍微復雜了一點,全是體力活兒:
<1> 既然是數組里面,那肯定要先測量數組的大小,然后根據大小循環拿;
<2> 拿到一個數組項,然后把這個項先轉化成普通的json字符串,也就是 char *s 能接受的。
<3>再次將這個json字符串,轉化成一個json對象
<4> 按照拿普通對象中的東西那樣開干就行了。
ps:曾經試過直接在數組項中拿內容,失敗了,不知為何,于是就按照這個4步開干了。
比如:
1 {\"list\":[{\"name\":\"xiao hong\",\"age\":10},{\"name\":\"hua hua\",\"age\":11}]}
是的.list 是一個數組,數組里面有兩個對象,那么代碼如下:
復制代碼
?1 int main(int argc, char **argv)
?2 {
?3 char *s = "{\"list\":[{\"name\":\"xiao hong\",\"age\":10},{\"name\":\"hua hua\",\"age\":11}]}";
?4 cJSON *root = cJSON_Parse(s);
?5 if(!root) {
?6???? printf("get root faild !\n");
?7???? return -1;
?8 }
?9 cJSON *js_list = cJSON_GetObjectItem(root, "list");
10 if(!js_list){
11???? printf("no list!\n");
12???? return -1;
13 }
14 int array_size = cJSON_GetArraySize(js_list);
15 printf("array size is %d\n",array_size);
16 int i = 0;
17 cJSON *item,*it, *js_name, *js_age;
18 char *p? = NULL;
19 for(i=0; i< array_size; i++) {
20???? item = cJSON_GetArrayItem(js_list, i);
21???? if(!item) {
22???????? //TODO...
23???? }
24???? p = cJSON_PrintUnformatted(item);
25???? it = cJSON_Parse(p);
26???? if(!it)
27???????? continue ;
28???? js_name = cJSON_GetObjectItem(it, "name");
29???? printf("name is %s\n",js_name->valuestring);
30???? js_age = cJSON_GetObjectItem(it, "age");
31???? printf("age is %d\n",js_age->valueint);
32
33 }
34
35 if(root)
36???? cJSON_Delete(root);
37???? return 0;
38 }
復制代碼
按理說,應該釋放下 it 變量才對,但似乎事實不是這樣,僅僅可以釋放根root。
好了,json 解析,無非就是上面的組合了,還能有什么呢?
?
解析和封裝都有了,此文結束了。
看這里:
https://github.com/boyisgood86/learning/tree/master/cjson
?
good luck !
?
?
update:? 上面第四部分會導致內存泄露,修改方法見貼圖:
??????????????????????????????????????????????????????????????????????????????????????????????????????? 使????? 用??????????????????????????????????????????????????????????????????????????????????????????????????? ?
?????? cJSON 開源項目位置:? http://sourceforge.net/projects/cjson/
?????? cJSON,目前來說,就只有兩個文件,一個cJSON.c 一個cJSON.h文件。使用的時候,自己創建好一個main.c文件后,如果是在linux pc上,請使用以下命令進行編譯:
?
1 gcc -g -Wall *.c -l m
就會默認生成一個 a.out文件,執行即可。在linux下編譯的時候,注意鏈接 libm 庫。
?????? 整個項目都是以極標準的C來寫的,意思說,可以跨各種平臺使用了。不過,還是有兩三處需要微調一下<針對stm32f103? + rt_thread >。其中修改一下malloc & free & size_t 這三個東西:
?46 static void *(*cJSON_malloc)(size_t sz) = malloc;
?47 static void (*cJSON_free)(void *ptr) = free;
----------------------------------------
?46 static void *(*cJSON_malloc)(size_t sz) = rt_malloc;
?47 static void (*cJSON_free)(void *ptr) = rt_free;
復制代碼
?60 void cJSON_InitHooks(cJSON_Hooks* hooks)
?61 {
?62???? if (!hooks) { /* Reset hooks */
?63???????? cJSON_malloc = malloc;
?64???????? cJSON_free = free;
?65???????? return;
?66???? }
?67
?68???? cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
?69???? cJSON_free?? = (hooks->free_fn)?hooks->free_fn:free;
?70 }
----------------------------------------------------
?60 void cJSON_InitHooks(cJSON_Hooks* hooks)
?61 {
?62???? if (!hooks) { /* Reset hooks */
?63???????? cJSON_malloc = rt_malloc;
?64???????? cJSON_free = rt_free;
?65???????? return;
?66???? }
?67
?68???? cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:rt_malloc;
?69???? cJSON_free?? = (hooks->free_fn)?hooks->free_fn:rt_free;
?70 }
復制代碼
free & malloc就這么兩個地方要修改一下吧,其中size_t 這個應該是在 .h 文件修改,主要是rtt的 rt_malloc 和這里的malloc使用的不同,所以修改了下---不一定非要修改。
所以,這東西說實話,也不存在什么移植不移植的問題了。很輕松的就可以在各個平臺使用了。
?????????????????????????????????????????????????????????????????????????????????????????????????? 例?????? 程???????????????????????????????????????????????????????????????????????????????????????????????????????? ?
????? 不對json的格式進行說明了,下面直接記下使用方法了。
????? 第一,創建json數據串。這數據串,可能是對象,也可能是數組,也可能是它們的各種組合,其中再加上一些鍵值對。有一點要先說明:它們的組合,符合父子繼承格式--這也是json數據串的特點。
???? <1>? 創建一個對象,并在這個對象里面添加一個字符串鍵值和一個數字鍵值:
復制代碼
?1 int create_js(void)
?2 {
?3???? cJSON *root;
?4???? /*create json string root*/
?5???? root = cJSON_CreateObject();
?6???? if(!root) {
?7???????? DEBUG("get root faild !\n");
?8???????? goto EXIT;
?9???? }else DEBUG("get root success!\n");
10
11???? {
12???????? cJSON * js_body ;
13
14???????? const char *const body = "body";
15???????? cJSON_AddItemToObject(root, body, js_body=cJSON_CreateObject());
16???????? cJSON_AddStringToObject(js_body,"name","xiaohui");
17???????? cJSON_AddNumberToObject(js_body,"value",600);
18???????? {
19???????? char *s = cJSON_PrintUnformatted(root);
20???????? if(s){
21???????????? DEBUG("create js string is %s\n",s);
22???????????? free(s);
23???????? }
24???????? }
25???????? cJSON_Delete(root);
26???? }
27
28???? return 0;
29 EXIT:
30???? return -1;
31 }
32
33 int main(int argc, char **argv)
34 {
35???? create_js();
36???? return 0;
37 }
復制代碼
運行結果:
1 create js string is? {"body":{"name":"xiaohui","value":600}}
說明: 創建根對象,使用? cJSON_CreateObject(); 這個API,返回的是一個 cJSON的指針,注意,在這個指針用完了以后,需要手工調用 cJSON_Delete(root); 進行內存回收。
創建body對象的時候,是在根對象的基礎上進行創建,而插入name 和value的時候,是以body為父節點。需要注意的是? json 格式的數據,雖然也是一個字符串的樣子,但這個時候還是無法當成普通的字符串進行使用,需要調用 cJSON_PrintUnformatted(root) 或者 cJSON_Print(root);來將json對象轉換成普通的字符串,并且都是以該json對象的根為基點。兩個API的區別即是:一個是沒有格式的:也就是轉換出的字符串中間不會有"\n" "\t"之類的東西存在,而cJSON_Print(root);打印出來是人看起來很舒服的格式。僅此而已。
<2> 創建一個數組,并向數組添加一個字符串和一個數字:
復制代碼
?1 int create_js(void)
?2 {
?3???? cJSON *root, *js_body;
?4???? root = cJSON_CreateArray();
?5???? cJSON_AddItemToArray(root, cJSON_CreateString("Hello world"));
?6???? cJSON_AddItemToArray(root, cJSON_CreateNumber(10));
?7???? {
?8 //??????? char *s = cJSON_Print(root);
?9???????? char *s = cJSON_PrintUnformatted(root);
10???????? if(s){
11???????????? DEBUG(" %s \n",s);
12???????????? free(s);
13???????? }
14???? }
15???? if(root)
16???? cJSON_Delete(root);
17
18???? return 0;
19 EXIT:
20???? return -1;
21 }
22
23 int main(int argc, char **argv)
24 {
25???? create_js();
26???? return 0;
27 }
復制代碼
運行結果:
1 ["Hello world",10]
<3> 對象里面包括一個數組,數組里面包括對象,對象里面再添加一個字符串和一個數字:
復制代碼
?1 int create_js(void)
?2 {
?3???? cJSON *root, *js_body, *js_list;
?4???? root = cJSON_CreateObject();
?5???? cJSON_AddItemToObject(root,"body", js_body = cJSON_CreateArray());
?6???? cJSON_AddItemToArray(js_body, js_list = cJSON_CreateObject());
?7???? cJSON_AddStringToObject(js_list,"name","xiaohui");
?8???? cJSON_AddNumberToObject(js_list,"status",100);
?9
10???? {
11???????? //??????? char *s = cJSON_Print(root);
12???????? char *s = cJSON_PrintUnformatted(root);
13???????? if(s){
14???????????? DEBUG(" %s \n",s);
15???????????? free(s);
16???????? }
17???? }
18???? if(root)
19???????? cJSON_Delete(root);
20
21???? return 0;
22 EXIT:
23???? return -1;
24 }
25
26 int main(int argc, char **argv)
27 {
28???? create_js();
29???? return 0;
30 }
復制代碼
運行結果:
1 {"body":[{"name":"xiaohui","status":100}]}
<4>其他組合就依次類推,只要搞清楚父子關系即可。隨便嵌套隨便玩。不再貼了。
?? <第二, 解析json數據串>
?? 步驟: 1? 先將普通的json 字符串 處理成 json對象格式。 2? 根據關鍵字進行解析,解析的時候,需要根據關鍵字值的類型進行判斷,而這些類型,已經在cJSON.h里面寫明白了,包括:對象、數組、普通字符串、普通變量等等。
?? <偷個懶吧,將自己學習的時候用的資料現貼過來,后面休息一下再詳細補充自己在工程中的解析方法>
http://blog.csdn.net/xukai871105/article/details/17094113
http://blog.sina.com.cn/s/blog_a6fb6cc90101ffme.html
?
<當然,他寫的比較簡潔,還有些可以補充的---其實我已經在上面使用文字進行補充過了。當然,不同的工程,可能解析的方法和側重點并不相同>
?
?
或許,是時候把解析的部分補充上來了:
處理流程:
1, 先將普通的json串處理成json對象,也就是所謂的創建json root的過程,只有一行代碼即可:
cJSON *root;
root = cJSON_Parse(js_string);
ps:需要注意的是,這個root在解析完成后,需要釋放掉,代碼如下:
if (root)
? cJSON_Delete(root);
2,開始拿關鍵字,但如果關鍵字還有父層或者祖層,那就需要先從父層開拿,所謂剝洋蔥是也!
先說沒有父層的:
{"name":"xiaohong","age":10}
這個字符串這樣拿即可:
復制代碼
?1 char *s = "{\"name\":\"xiao hong\",\"age\":10}";
?2 cJSON *root = cJSON_Parse(s);
?3 if(!root) {
?4???? printf("get root faild !\n");
?5???? return -1;
?6 }
?7 cJSON *name = cJSON_GetObjectItem(root, "name");
?8 if(!name) {
?9???? printf("No name !\n");
10???? return -1;
11 }
12 printf("name type is %d\n",name->type);
13 printf("name is %s\n",name->valuestring);
14
15 cJSON *age = cJSON_GetObjectItem(root, "age");
16 if(!age) {
17???? printf("no age!\n");
18???? return -1;
19 }
20 printf("age type is %d\n", age->type);
21 printf("age is %d\n",age->valueint);
復制代碼
顯示結果:
1 name type is 4
2 name is xiao hong
3 age type is 3
4 age is 10
需要注意的是: 上面的type 已經在cJSON.h里面定義好了,有自己的意義。如果是在嚴格的場所,應該先判定該 item的type,然后再考慮去拿值。
而如果有父層的話,無非就是接著向下拿就是了,稍微修改下前面的demo吧:
處理這串數據吧:
{\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}
復制代碼
?1 char *s = "{\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}";
?2 cJSON *root = cJSON_Parse(s);
?3 if(!root) {
?4???? printf("get root faild !\n");
?5???? return -1;
?6 }
?7
?8 cJSON *js_list = cJSON_GetObjectItem(root, "list");
?9 if(!js_list) {
10???? printf("no list!\n");
11???? return -1;
12 }
13 printf("list type is %d\n",js_list->type);
14
15 cJSON *name = cJSON_GetObjectItem(js_list, "name");
16 if(!name) {
17???? printf("No name !\n");
18???? return -1;
19 }
20 printf("name type is %d\n",name->type);
21 printf("name is %s\n",name->valuestring);
22
23 cJSON *age = cJSON_GetObjectItem(js_list, "age");
24 if(!age) {
25???? printf("no age!\n");
26???? return -1;
27 }
28 printf("age type is %d\n", age->type);
29 printf("age is %d\n",age->valueint);
30
31 cJSON *js_other = cJSON_GetObjectItem(root, "other");
32 if(!js_other) {
33???? printf("no list!\n");
34???? return -1;
35 }
36 printf("list type is %d\n",js_other->type);
37
38 cJSON *js_name = cJSON_GetObjectItem(js_other, "name");
39 if(!js_name) {
40???? printf("No name !\n");
41???? return -1;
42 }
43 printf("name type is %d\n",js_name->type);
44 printf("name is %s\n",js_name->valuestring);
45
46 if(root)
47???? cJSON_Delete(root);
48???? return 0;
復制代碼
打印結果:
復制代碼
1 list type is 6
2 name type is 4
3 name is xiao hong
4 age type is 3
5 age is 10
6 list type is 6
7 name type is 4
8 name is hua hua
復制代碼
所謂子子孫孫無窮盡也,按照上面那個方法推下去即可。
3,json 里數組怎么取?
1 {\"list\":[\"name1\",\"name2\"]}
代碼如下:
復制代碼
?1 int main(int argc, char **argv)
?2 {
?3 char *s = "{\"list\":[\"name1\",\"name2\"]}";
?4 cJSON *root = cJSON_Parse(s);
?5 if(!root) {
?6???? printf("get root faild !\n");
?7???? return -1;
?8 }
?9 cJSON *js_list = cJSON_GetObjectItem(root, "list");
10 if(!js_list){
11???? printf("no list!\n");
12???? return -1;
13 }
14 int array_size = cJSON_GetArraySize(js_list);
15 printf("array size is %d\n",array_size);
16 int i = 0;
17 cJSON *item;
18 for(i=0; i< array_size; i++) {
19???? item = cJSON_GetArrayItem(js_list, i);
20???? printf("item type is %d\n",item->type);
21???? printf("%s\n",item->valuestring);
22 }
23
24 if(root)
25???? cJSON_Delete(root);
26???? return 0;
27 }
復制代碼
對頭,好簡單的樣子<在別人的庫上使用>
?
4? 如果json數組里面又搞了對象怎么辦?
不怕搞對象,就怕這樣搞對象? 無他,就是稍微復雜了一點,全是體力活兒:
<1> 既然是數組里面,那肯定要先測量數組的大小,然后根據大小循環拿;
<2> 拿到一個數組項,然后把這個項先轉化成普通的json字符串,也就是 char *s 能接受的。
<3>再次將這個json字符串,轉化成一個json對象
<4> 按照拿普通對象中的東西那樣開干就行了。
ps:曾經試過直接在數組項中拿內容,失敗了,不知為何,于是就按照這個4步開干了。
比如:
1 {\"list\":[{\"name\":\"xiao hong\",\"age\":10},{\"name\":\"hua hua\",\"age\":11}]}
是的.list 是一個數組,數組里面有兩個對象,那么代碼如下:
復制代碼
?1 int main(int argc, char **argv)
?2 {
?3 char *s = "{\"list\":[{\"name\":\"xiao hong\",\"age\":10},{\"name\":\"hua hua\",\"age\":11}]}";
?4 cJSON *root = cJSON_Parse(s);
?5 if(!root) {
?6???? printf("get root faild !\n");
?7???? return -1;
?8 }
?9 cJSON *js_list = cJSON_GetObjectItem(root, "list");
10 if(!js_list){
11???? printf("no list!\n");
12???? return -1;
13 }
14 int array_size = cJSON_GetArraySize(js_list);
15 printf("array size is %d\n",array_size);
16 int i = 0;
17 cJSON *item,*it, *js_name, *js_age;
18 char *p? = NULL;
19 for(i=0; i< array_size; i++) {
20???? item = cJSON_GetArrayItem(js_list, i);
21???? if(!item) {
22???????? //TODO...
23???? }
24???? p = cJSON_PrintUnformatted(item);
25???? it = cJSON_Parse(p);
26???? if(!it)
27???????? continue ;
28???? js_name = cJSON_GetObjectItem(it, "name");
29???? printf("name is %s\n",js_name->valuestring);
30???? js_age = cJSON_GetObjectItem(it, "age");
31???? printf("age is %d\n",js_age->valueint);
32
33 }
34
35 if(root)
36???? cJSON_Delete(root);
37???? return 0;
38 }
復制代碼
按理說,應該釋放下 it 變量才對,但似乎事實不是這樣,僅僅可以釋放根root。
好了,json 解析,無非就是上面的組合了,還能有什么呢?
?
解析和封裝都有了,此文結束了。
看這里:
https://github.com/boyisgood86/learning/tree/master/cjson
?
good luck !
?
?
update:? 上面第四部分會導致內存泄露,修改方法見貼圖:
總結
以上是生活随笔為你收集整理的cJSON 使用笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 几步实现stm32上面移植mqtt
- 下一篇: FreeRTOS实验_独立看门狗监视多线