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
cJSON.c