1.下载:“https://github.com/DaveGamble/cJSON.git”
2.解压 unzip XXX.zip
3.cJson.c,cJSON.h拷贝到自定义的目录
4.编译:gcc cJSON.c test.c -o test -lm (添加数学库)
5.基于JSON相关的c函数库,生成json文件
从缓冲区中解析出JSON结构:extern cJSON *cJSON_Parse(const char *value);
解析一块JSON数据返回cJSON结构, 在使用完之后调用cJSON_Delete函数释放json对象结构。
将传入的JSON结构转化为字符串 :extern char *cJSON_Print(cJSON *item);
可用于输出到输出设备, 使用完之后free(char *) 。
将JSON结构所占用的数据空间释放 :void cJSON_Delete(cJSON *c)
创建一个值类型的数据 :extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
创建一个对象(文档) :extern cJSON *cJSON_CreateObject(void);
数组创建以及添加 :cJSON *cJSON_CreateIntArray(const int *numbers,int count);
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
JSON嵌套 :
【 向对象中增加键值对】 cJSON_AddItemToObject(root, “rows”, 值类型数据相关函数());
【 向对象中增加数组】 cJSON_AddItemToObject(root, “rows”, cJSON_CreateArray());
【 向数组中增加对象】 cJSON_AddItemToArray(rows, cJSON_CreateObject());
几个能提高操作效率的宏函数 :#define cJSON_AddNumberToObject(object,name,n)
cJSON_AddItemToObject(object, name,cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s)
cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
根据键找json结点 :extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)
判断是否有key是string的项 如果有返回1 否则返回0 :
extern int cJSON_HasObjectItem(cJSON *object,const char *string)
{ return cJSON_GetObjectItem(object,string)?1:0; }
返回数组结点array中成员的个数 :extern int cJSON_GetArraySize(cJSON *array);
根据数组下标index取array数组结点的第index个成员 返回该成员节点 :extern cJSON *cJSON_GetArrayItem(cJSON *array,int index);
遍历数组 :#define cJSON_ArrayForEach(pos, head) for(pos = (head)->child; pos != NULL; pos = pos->next)
cJSON_CreateObject函数可创建一个根数据项,之后便可向该根数据项中添加string或int等内容,返回的是一个 cJSON的指针,注意,在这个指针用完了以后,需要手工调用 cJSON_Delete(root); 进行内存回收。
cJSON_AddNumberToObject向节点中添加子节点,例如此处添加name节点,节点值为字符串"fengxin"
需要注意的是 json 格式的数据,虽然也是一个字符串的样子,但这个时候还是无法当成普通的字符串进行使用,需要调用 cJSON_PrintUnformatted(root) 或者 cJSON_Print(root);来将json对象转换成普通的字符串,并且都是以该json对象的根为基点。两个API的区别即是:一个是没有格式的:也就是转换出的字符串中间不会有"\n" "\t"之类的东西存在,而cJSON_Print(root);打印出来是人看起来很舒服的格式。
因为函数内部封装有malloc函数,所以使用free函数释放被out占用的内存空间
接下来,我们创建一个Json文件,然后对这个json文件进行创建和解析。
{
"wb":3,
"book":"dddd",
"author":"wanger",
"books":[
{
"name":"www",
"type":"123"
},
{
"name":"eee",
"type":"456"
}
],
"sem":{
"post":{
"name":"wangsan"
}
}
}
可以使用在线JSON工具测一下
创建cJSON文件的步骤:
我们来写程序:
#include
#include
#include"cJSON.h"
int main()
{
//创建空对象
cJSON* root = cJSON_CreateObject();
cJSON* item = cJSON_CreateObject();
cJSON* next = cJSON_CreateObject();
cJSON* obj = cJSON_CreateObject();
//在root节点下添加
cJSON_AddItemToObject(root,"wb",cJSON_CreateNumber(3));
cJSON_AddItemToObject(root,"book",cJSON_CreateString("dddd"));
cJSON_AddItemToObject(root,"author",cJSON_CreateString("wanger"));
//添加数组
cJSON* array = NULL;
cJSON_AddItemToObject(root,"books",array=cJSON_CreateArray());
//添加数组对象
cJSON_AddItemToArray(array,obj);
cJSON_AddItemToObject(obj,"name",cJSON_CreateString("www"));
cJSON_AddStringToObject(obj,"type","123");
cJSON_AddItemToArray(array,obj=cJSON_CreateObject());
cJSON_AddItemToObject(obj,"name",cJSON_CreateString("eee"));
cJSON_AddStringToObject(obj,"type","456");
cJSON_AddItemToObject(root, "sem", item);//root节点下添加sem节点
cJSON_AddItemToObject(item, "slots", next);//se节点下添加item节点
cJSON_AddItemToObject(next, "name", cJSON_CreateString("wangsan"));//添加name节点
printf("%s\n", cJSON_Print(root));
FILE *fp = fopen("create.json","w");
char *buf = cJSON_Print(root);
fwrite(buf,strlen(buf),1,fp);
fclose(fp);
cJSON_Delete(root);
return 0;
}
结果:
{
"wb": 3,
"book": "dddd",
"author": "wanger",
"books": [{
"name": "www",
"type": "123"
}, {
"name": "eee",
"type": "456"
}],
"sem": {
"slots": {
"name": "wangsan"
}
}
}
解析cJSON文件:
步骤:
#include
#include
#include
#include"cJSON.h"
int main()
{
char *string = "{\"zoom\":[\"mpnkey\",\"hourse\",\"panda\"]}";
cJSON* root = cJSON_Parse(string);
cJSON* node = NULL;
node = cJSON_GetObjectItem(root,"zoom");
if(NULL == node)
{
printf("node is noit find\n");
return -1;
}
int array_size = cJSON_GetArraySize(node);
printf("array size is %d\n ",array_size);
int i = 0;
cJSON* item;
for(i=0;itype);
printf("valuestring is %s\n",item->valuestring);
}
if(root)
{
cJSON_Delete(root);
return 0;
}
return 0;
}
结果:
array size is 3
item type is 16
valuestring is mpnkey
item type is 16
valuestring is hourse
item type is 16
valuestring is panda
参考网友还有其他类型的解析,摘录一下,方便自己学习
1.父层的:
out={\"name\":\"fengxin\",\"passwd\":\"123\",\"num\":1}
#include
#include
#include
#include"cJSON.h"
int main()
{
cJSON *json,*json_name,*json_passwd,*json_num;
char* out="{\"name\":\"fengxin\",\"passwd\":\"123\",\"num\":1}";
json = cJSON_Parse(out); //解析成json形式
json_name = cJSON_GetObjectItem( json , "name" ); //获取键值内容
json_passwd = cJSON_GetObjectItem( json , "passwd" );
json_num = cJSON_GetObjectItem( json , "num" );
printf("name:%s,passwd:%s,num:%d\n",json_name->valuestring,json_passwd->valuestring,json_num->valueint);
cJSON_Delete(json); //释放内存
free(out);
}
显示结果:
name:fengxin,passwd:123,num:1
out={\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}
char *s = "{\"list\":{\"name\":\"xiao hong\",\"age\":10},\"other\":{\"name\":\"hua hua\"}}";
cJSON *root = cJSON_Parse(s);
if(!root) {
printf("get root faild !\n");
return -1;
}
cJSON *js_list = cJSON_GetObjectItem(root, "list");
if(!js_list) {
printf("no list!\n");
return -1;
}
printf("list type is %d\n",js_list->type);
cJSON *name = cJSON_GetObjectItem(js_list, "name");
if(!name) {
printf("No name !\n");
return -1;
}
printf("name type is %d\n",name->type);
printf("name is %s\n",name->valuestring);
cJSON *age = cJSON_GetObjectItem(js_list, "age");
if(!age) {
printf("no age!\n");
return -1;
}
printf("age type is %d\n", age->type);
printf("age is %d\n",age->valueint);
cJSON *js_other = cJSON_GetObjectItem(root, "other");
if(!js_other) {
printf("no list!\n");
return -1;
}
printf("list type is %d\n",js_other->type);
cJSON *js_name = cJSON_GetObjectItem(js_other, "name");
if(!js_name) {
printf("No name !\n");
return -1;
}
printf("name type is %d\n",js_name->type);
printf("name is %s\n",js_name->valuestring);
if(root)
cJSON_Delete(root);
return 0;
打印结果:
list type is 6
name type is 4
name is xiao hong
age type is 3
age is 10
list type is 6
name type is 4
name is hua hua
3.数组取值
{\"list\":[\"name1\",\"name2\"]}
int main(int argc, char **argv)
{
char *s = "{\"list\":[\"name1\",\"name2\"]}";
cJSON *root = cJSON_Parse(s);
if(!root) {
printf("get root faild !\n");
return -1;
}
cJSON *js_list = cJSON_GetObjectItem(root, "list");
if(!js_list){
printf("no list!\n");
return -1;
}
int array_size = cJSON_GetArraySize(js_list);
printf("array size is %d\n",array_size);
int i = 0;
cJSON *item;
for(i=0; i< array_size; i++) {
item = cJSON_GetArrayItem(js_list, i);
printf("item type is %d\n",item->type);
printf("%s\n",item->valuestring);
}
if(root)
cJSON_Delete(root);
return 0;
}
4…如果json数组里面又搞了对象怎么办?
不怕搞对象,就怕这样搞对象? 无他,就是稍微复杂了一点,全是体力活儿:
<1> 既然是数组里面,那肯定要先测量数组的大小,然后根据大小循环拿;
<2> 拿到一个数组项,然后把这个项先转化成普通的json字符串,也就是 char *s 能接受的。
<3>再次将这个json字符串,转化成一个json对象
<4> 按照拿普通对象中的东西那样开干就行了。
{\"list\":[{\"name\":\"xiao hong\",\"age\":10},{\"name\":\"hua hua\",\"age\":11}]}
list 是一个数组,数组里面有两个对象,那么代码如下
int main(int argc, char **argv)
{
char *s = "{\"list\":[{\"name\":\"xiao hong\",\"age\":10},{\"name\":\"hua hua\",\"age\":11}]}";
cJSON *root = cJSON_Parse(s);
if(!root) {
printf("get root faild !\n");
return -1;
}
cJSON *js_list = cJSON_GetObjectItem(root, "list");
if(!js_list){
printf("no list!\n");
return -1;
}
int array_size = cJSON_GetArraySize(js_list);
printf("array size is %d\n",array_size);
int i = 0;
cJSON *item,*it, *js_name, *js_age;
char *p = NULL;
for(i=0; i< array_size; i++) {
item = cJSON_GetArrayItem(js_list, i);
if(!item) {
//TODO...
}
p = cJSON_PrintUnformatted(item);
it = cJSON_Parse(p);
if(!it)
continue ;
js_name = cJSON_GetObjectItem(it, "name");
printf("name is %s\n",js_name->valuestring);
js_age = cJSON_GetObjectItem(it, "age");
printf("age is %d\n",js_age->valueint);
}
if(root)
cJSON_Delete(root);
return 0;
}