ANSI C中的超輕量級JSON解析器
JSON(JavaScript對象表示法)是一種輕量級的數據交換格式。人類易於閱讀和書寫。機器很容易解析和生成。它基於JavaScript編程語言標准ECMA-262第三版(1999年12月)的子集 。JSON是一種完全獨立於語言的文本格式,但是使用C語言家族(包括C,C ++,C#,Java,JavaScript,Perl,Python等)的程序員熟悉的約定。這些屬性使JSON成為理想的數據交換語言。
cJSON旨在成為您可以完成工作的最簡單的解析器。它是資源只有一個C的頭文件和C文件,所以方便移植。它可以為你各種需要的json字符串處理,包括打包、解析、修改、刪除、添加等。在這里將一探究竟。
在這里將着重敘述json的打包和解析,更多處理玩法,見文章末尾鏈接。
開始cJSON
cJSON合並到您的項目
因為整個庫只有一個C文件和一個頭文件,所以您只需復制cJSON.h並復制cJSON.c到項目源並開始使用它。
cJSON用ANSI C(C89)編寫,以便支持盡可能多的平台和編譯器。
下載:
https://github.com/DaveGamble/cJSON/releases
Cjson結構體
/* The cJSON structure: */
typedef struct cJSON
{
struct cJSON *next;
struct cJSON *prev;
struct cJSON *child;
int type;
char *valuestring;
int valueint;
double valuedouble;
char *string;
} cJSON;
結構體項解析:
next 和prev :Cjson結構體作為一個雙向連表的環,可以通過 next 和prev 指針進行連表遍歷
child:可以是cJSON_Array、cJSON_Object類型數據
type:當前項的類型
valuestring:內容存儲,當類型是cJSON_String和cJSON_Raw
valueint:內容存儲,整型,可以是cJSON_False、cJSON_True數據
valuedouble:內容存儲,浮點型,當類型是cJSON_Number
string:鍵名
數據類型
l cJSON_Invalid表示一個不包含任何值的無效項目。如果將項目設置為全零字節,則將自動具有此類型。
l cJSON_False表示一個false布爾值。您也可以使用來檢查布爾值cJSON_IsBool
l cJSON_True表示一個true布爾值。您也可以使用來檢查布爾值cJSON_IsBool
l cJSON_NULL表示一個null值
l cJSON_Number 表示一個數字值。該值存儲為double in valuedouble和in valueint。如果數字超出整數范圍,INT_MAX或INT_MIN用於valueint
l cJSON_String表示一個字符串值。它以零終止字符串的形式存儲在中valuestring
l cJSON_Array表示一個數組值。這是通過指向表示數組中值child的cJSON項目的鏈接列表來實現的。使用next和將元素鏈接在一起prev,其中第一個元素具有prev.next == NULL和最后一個元素next == NULL
l cJSON_Object 表示一個對象值。對象的存儲方式與數組相同,唯一的區別是對象中的項將其鍵存儲在中string
l cJSON_Raw表示以JSON字符存儲的零終止形式的任何JSON valuestring。例如,可以使用它來避免一遍又一遍地打印相同的靜態JSON以節省性能。解析時,cJSON永遠不會創建此類型。另請注意,cJSON不會檢查其是否為有效JSON。
類型
#define cJSON_Invalid (0) #define cJSON_False (1 << 0) #define cJSON_True (1 << 1) #define cJSON_NULL (1 << 2) #define cJSON_Number (1 << 3) #define cJSON_String (1 << 4) #define cJSON_Array (1 << 5) #define cJSON_Object (1 << 6) #define cJSON_Raw (1 << 7) /* raw json */
類型判斷
cJSON_IsInvalid(const cJSON * const item); cJSON_IsFalse(const cJSON * const item); cJSON_IsTrue(const cJSON * const item); cJSON_IsBool(const cJSON * const item); cJSON_IsNull(const cJSON * const item); cJSON_IsNumber(const cJSON * const item); cJSON_IsString(const cJSON * const item); cJSON_IsArray(const cJSON * const item); cJSON_IsObject(const cJSON * const item); cJSON_IsRaw(const cJSON * const item);
注意
創建cjson對象后,處理完需要進行內存釋放:
如果是cjson里的對象,請使用cJSON_Delete()
如果不是對象:cJSON_free()或free()
零字符
cJSON不支持包含零字符'\0'或的字符串\u0000。對於當前的API,這是不可能的,因為字符串以零結尾。
字符編碼
cJSON僅支持UTF-8編碼的輸入。但是在大多數情況下,它不會拒絕無效的UTF-8作為輸入,而只是將其原樣傳播。只要輸入不包含無效的UTF-8,輸出將始終是有效的UTF-8。
C標准
cJSON用ANSI C(或C89,C90)編寫。如果您的編譯器或C庫未遵循此標准,則不能保證正確的行為。
注意:ANSI C不是C ++,因此不應使用C ++編譯器進行編譯。您可以使用C編譯器對其進行編譯,然后將其與C ++代碼鏈接。盡管可以使用C ++編譯器進行編譯,但是不能保證正確的行為。
浮點數字
double除IEEE754雙精度浮點數外,cJSON不正式支持任何實現。它可能仍然可以與其他實現一起使用,但是這些實現的錯誤將被視為無效。
目前,cJSON支持的浮點文字的最大長度為63個字符。
數組和對象的深層嵌套
cJSON不支持嵌套太深的數組和對象,因為這會導致堆棧溢出。為了防止這種CJSON_NESTING_LIMIT情況,默認情況下,cJSON將深度限制為1000,但是可以在編譯時進行更改。
格式化輸出
按標准的格式輸出json字符串,輸出完后一定要記得釋放內存

代碼
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 //待解析字符串
6 char *json_str="{\"key1\":\"dongxiaodong\",\"key2\":1998,\"key3\":55778}";
7
8 //輸出原字符串
9 printf("原字符串:%s\r\n",json_str);
10
11 //解析成json對象
12 cJSON * json_obj = cJSON_Parse(json_str);
13
14 //格式輸出
15 char *json_print_str=NULL;
16 json_print_str=cJSON_Print(json_obj);
17 printf("\r\n輸出內容:\r\n\r\n%s\r\n",json_print_str);
18
19 //釋放資源
20 free(json_print_str);
21
22 //釋放資源
23 cJSON_Delete(json_obj);
24 }
json打包
cJSON_CreateObject函數可創建一個根數據項,在此之后就可以添加各種數據類型的子節點了,使用完成后需要通過cJSON_Delete()釋放內存。
創建一層級的json

代碼:
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 cJSON *root_obj = NULL;//根,json對象
6 char *out_str = NULL; //輸出結果
7 root_obj =cJSON_CreateObject();//創建
8 //添加一個字符串,參數(根對象,鍵,值)
9 cJSON_AddStringToObject(root_obj, "key1", "dongxiaodong");
10 //添加一個整型,參數(根對象,鍵,值)
11 cJSON_AddNumberToObject(root_obj, "key2",1998);
12 //添加一個浮點型,參數(根對象,鍵,值)
13 cJSON_AddNumberToObject(root_obj, "key3",22.33);
14 //添加一個bool類型,參數(根對象,鍵,值)
15 //bool值可以是0/1或false/true
16 cJSON_AddBoolToObject(root_obj, "key4",0);
17 //將json對象打包成字符串
18 out_str = cJSON_PrintUnformatted(root_obj);
19 //銷毀json對象,釋放內存
20 cJSON_Delete(root_obj);
21 //輸出值:{"key1":"dongxiaodong","key2":1998,"key3":22.33,"key4":false}
22 printf("%s",out_str);
23 }
類型創建函數還有:
cJSON_AddNullToObject(cJSON * const object, const char * const name);
cJSON_AddTrueToObject(cJSON * const object, const char * const name);
cJSON_AddFalseToObject(cJSON * const object, const char * const name);
cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
cJSON_AddObjectToObject(cJSON * const object, const char * const name);
cJSON_AddArrayToObject(cJSON * const object, const char * const name);
創建多層級的json

代碼:
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 cJSON *root_obj = NULL;//根,json對象
6 cJSON *item_obj = NULL;//二級json對象
7 char *out_str = NULL; //輸出結果
8
9 root_obj =cJSON_CreateObject();//創建
10 //添加一個字符串,參數(根對象,鍵,值)
11 cJSON_AddStringToObject(root_obj, "key1", "dongxiaodong");
12 //添加一個整型,參數(根對象,鍵,值)
13 cJSON_AddNumberToObject(root_obj, "key2",1998);
14
15 //創建一個子json對象
16 item_obj= cJSON_AddObjectToObject(root_obj,"myson");
17 //向孩子對象中添加內容
18 cJSON_AddStringToObject(item_obj, "sonkey1", "東小東");
19 cJSON_AddNumberToObject(item_obj, "sonkey2",2020);
20
21 //將json對象打包成字符串
22 out_str = cJSON_PrintUnformatted(root_obj);
23 //銷毀json對象,釋放內存
24 cJSON_Delete(root_obj);
25 //輸出值:{"key1":"dongxiaodong","key2":1998,"myson":{"sonkey1":"東小東","sonkey2":2020}}
26 printf("%s",out_str);
27 }
創建多層json(數組形式)

代碼
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 cJSON *root_obj = NULL;//根,json對象
6 cJSON *item_obj = NULL;//數組對象
7 char *out_str = NULL; //輸出結果
8
9 root_obj =cJSON_CreateObject();//創建
10 //添加一個字符串,參數(根對象,鍵,值)
11 cJSON_AddStringToObject(root_obj, "key1", "dongxiaodong");
12 //添加一個整型,參數(根對象,鍵,值)
13 cJSON_AddNumberToObject(root_obj, "key2",1998);
14
15 //創建一個子數組對象
16 item_obj= cJSON_AddArrayToObject(root_obj,"myson");
17 //向數組對象中添加內容
18 cJSON_AddItemToArray(item_obj,cJSON_CreateTrue());
19 cJSON_AddItemToArray(item_obj,cJSON_CreateNumber(22));
20
21 //將json對象打包成字符串
22 out_str = cJSON_PrintUnformatted(root_obj);
23 //銷毀json對象,釋放內存
24 cJSON_Delete(root_obj);
25 //輸出值:{"key1":"dongxiaodong","key2":1998,"myson":[true,22]}
26 printf("%s",out_str);
27 }
創建的對象還可以是下面這些
cJSON_CreateNull(void);
cJSON_CreateTrue(void);
cJSON_CreateFalse(void);
cJSON_CreateBool(cJSON_bool boolean);
cJSON_CreateNumber(double num);
cJSON_CreateString(const char *string);
cJSON_CreateRaw(const char *raw);
cJSON_CreateArray(void);
cJSON_CreateObject(void);
創建混合json

代碼
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 cJSON *root_obj = NULL;//根,json對象
6 cJSON *son_obj=NULL;
7 cJSON *item_obj = NULL;//數組對象
8 char *out_str = NULL; //輸出結果
9
10 //根對象
11 root_obj =cJSON_CreateObject();//創建
12 //添加一個字符串,參數(根對象,鍵,值)
13 cJSON_AddStringToObject(root_obj, "key1", "dongxiaodong");
14 //添加一個整型,參數(根對象,鍵,值)
15 cJSON_AddNumberToObject(root_obj, "key2",1998);
16
17 //創建一個子數組對象
18 item_obj= cJSON_AddArrayToObject(root_obj,"myson");
19 //向數組對象中添加內容
20 cJSON_AddItemToArray(item_obj,cJSON_CreateTrue());
21 cJSON_AddItemToArray(item_obj,cJSON_CreateNumber(22));
22
23 //子對象
24 son_obj =cJSON_CreateObject();//創建
25 //添加一個字符串,參數(根對象,鍵,值)
26 cJSON_AddStringToObject(son_obj, "son1", "dongxiaodong");
27 //添加一個整型,參數(根對象,鍵,值)
28 cJSON_AddNumberToObject(son_obj, "son2",1998);
29 cJSON_AddItemToArray(item_obj,son_obj);
30
31 //將json對象打包成字符串
32 out_str = cJSON_PrintUnformatted(root_obj);
33 //銷毀json對象,釋放內存
34 cJSON_Delete(root_obj);
35 //輸出值:{"key1":"dongxiaodong","key2":1998,"myson":[true,22,{"son1":"dongxiaodong","son2":1998}]}
36 printf("%s",out_str);
37 }
json解析
解析一層級的json

代碼:
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 //待解析字符串
6 char *json_str="{\"key1\":\"dongxiaodong\",\"key2\":1998,\"key3\":22.33,\"key4\":true}";
7 //解析成json對象
8 cJSON * json_obj = cJSON_Parse(json_str);
9
10 //項存儲
11 cJSON *item=NULL;
12
13 //輸出原字符串
14 printf("原字符串:%s\r\n",json_str);
15
16 //獲取string類型
17 item=cJSON_GetObjectItem(json_obj,"key1");
18 printf("\r\nkey1:%s\r\n",item->valuestring);
19 cJSON_Delete(item);//釋放資源
20
21 //獲取數字
22 item=cJSON_GetObjectItem(json_obj,"key2");
23 printf("\r\nkey2:%d\r\n",item->valueint);
24 cJSON_Delete(item);//釋放資源
25
26 //獲取數字
27 item=cJSON_GetObjectItem(json_obj,"key3");
28 printf("\r\nkey3:%f\r\n",item->valuedouble);
29 cJSON_Delete(item);//釋放資源
30
31 //獲取bool
32 item=cJSON_GetObjectItem(json_obj,"key4");
33 printf("\r\nkey4:%d\r\n",item->valueint);
34 cJSON_Delete(item);//釋放資源
35
36 //是否資源
37 cJSON_Delete(json_obj);
38 }
解析多層級的json

代碼
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 //待解析字符串
6 char *json_str="{\"key1\":\"dongxiaodong\",\"key2\":1998,\"myson\":{\"sonkey1\":\"東小東\",\"sonkey2\":2020}}";
7 //解析成json對象
8 cJSON * json_obj = cJSON_Parse(json_str);
9
10 //項存儲
11 cJSON *item=NULL;
12 //內部項存儲
13 cJSON * item_item=NULL;
14
15 //輸出原字符串
16 printf("原字符串:%s\r\n",json_str);
17
18 //獲取string類型
19 item=cJSON_GetObjectItem(json_obj,"key1");
20 printf("\r\nkey1:%s\r\n",item->valuestring);
21 cJSON_Delete(item);//釋放資源
22
23 //獲取數字
24 item=cJSON_GetObjectItem(json_obj,"key2");
25 printf("\r\nkey2:%d\r\n",item->valueint);
26 cJSON_Delete(item);//釋放資源
27
28 //子串
29 item=cJSON_GetObjectItem(json_obj,"myson");
30 item_item=cJSON_GetObjectItem(item,"sonkey1");
31 printf("\r\nmyson(sonkey1):%s\r\n",item_item->valuestring);
32 cJSON_Delete(item_item);//釋放資源
33
34 item_item=cJSON_GetObjectItem(item,"sonkey2");
35 printf("\r\nmyson(sonkey2):%d\r\n",item_item->valueint);
36 cJSON_Delete(item_item);//釋放資源
37
38 cJSON_Delete(item);//釋放資源
39
40 //釋放資源
41 cJSON_Delete(json_obj);
42 }
解析多層json(數組形式)
代碼
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 //待解析字符串
6 char *json_str="{\"key1\":\"dongxiaodong\",\"key2\":1998,\"myson\":[true,113]}";
7 //解析成json對象
8 cJSON * json_obj = cJSON_Parse(json_str);
9
10 //項存儲
11 cJSON *item=NULL;
12 //內部項存儲
13 cJSON * item_item=NULL;
14
15 //輸出原字符串
16 printf("原字符串:%s\r\n",json_str);
17
18 //獲取string類型
19 item=cJSON_GetObjectItem(json_obj,"key1");
20 printf("\r\nkey1:%s\r\n",item->valuestring);
21 cJSON_Delete(item);//釋放資源
22
23 //獲取數字
24 item=cJSON_GetObjectItem(json_obj,"key2");
25 printf("\r\nkey2:%d\r\n",item->valueint);
26 cJSON_Delete(item);//釋放資源
27
28 //獲取子串
29 item=cJSON_GetObjectItem(json_obj,"myson");
30
31 //輸出數組大小
32 printf("\r\n數組大小:%d\r\n",cJSON_GetArraySize(item));
33
34 //輸出項1內容
35 item_item=cJSON_GetArrayItem(item,0);
36 printf("\r\nmyson(0):%d\r\n",item_item->valueint);
37 //cJSON_Delete(item_item);//釋放資源
38
39 //輸出項2內容
40 item_item=cJSON_GetArrayItem(item,1);
41 printf("\r\nmyson(1):%d\r\n",item_item->valueint);
42 cJSON_Delete(item_item);//釋放資源
43
44 cJSON_Delete(item);//釋放資源
45
46 //釋放資源
47 cJSON_Delete(json_obj);
48 }
解析混合json

代碼
1 #include <stdio.h>
2 #include "cJSON.h"
3 #include "cJSON.c"
4 void main(){
5 //待解析字符串
6 char *json_str="{\"key1\":\"dongxiaodong\",\"key2\":1998,\"myson\":[true,22,{\"son1\":\"dongxiaodong\",\"son2\":1998}]}";
7 //解析成json對象
8 cJSON * json_obj = cJSON_Parse(json_str);
9
10 //項存儲
11 cJSON *item=NULL;
12 //內部項存儲
13 cJSON * item_item=NULL;
14
15 //輸出原字符串
16 printf("原字符串:%s\r\n",json_str);
17
18 //獲取string類型
19 item=cJSON_GetObjectItem(json_obj,"key1");
20 printf("\r\nkey1:%s\r\n",item->valuestring);
21 cJSON_Delete(item);//釋放資源
22
23 //獲取數字
24 item=cJSON_GetObjectItem(json_obj,"key2");
25 printf("\r\nkey2:%d\r\n",item->valueint);
26 cJSON_Delete(item);//釋放資源
27
28 //獲取子串
29 item=cJSON_GetObjectItem(json_obj,"myson");
30
31 //輸出數組大小
32 printf("\r\n數組大小:%d\r\n",cJSON_GetArraySize(item));
33
34 //輸出項1內容
35 item_item=cJSON_GetArrayItem(item,0);
36 printf("\r\nmyson(0):%d\r\n",item_item->valueint);
37 //cJSON_Delete(item_item);//釋放資源
38
39 //輸出項2內容
40 item_item=cJSON_GetArrayItem(item,1);
41 printf("\r\nmyson(1):%d\r\n",item_item->valueint);
42 cJSON_Delete(item_item);//釋放資源
43
44 //項3內容
45 item_item=cJSON_GetArrayItem(item,2);
46 cJSON *item_item_son=NULL;
47
48 item_item_son =cJSON_GetObjectItem(item_item,"son1");
49 printf("\r\nmyson(2)(son1):%s\r\n",item_item_son->valuestring);
50 cJSON_Delete(item_item_son);//釋放資源
51
52 item_item_son =cJSON_GetObjectItem(item_item,"son2");
53 printf("\r\nmyson(2)(son2):%d\r\n",item_item_son->valueint);
54 cJSON_Delete(item_item_son);//釋放資源
55 cJSON_Delete(item_item);//釋放資源
56
57 cJSON_Delete(item);//釋放資源
58
59 //釋放資源
60 cJSON_Delete(json_obj);
61 }
附件:
cJSON.h
View Code
cJSON.c
View Code

