首先,要介绍一下什么是json格式。
一.JSON格式简述
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。(来自“开源中国”资料)。
如果是在linux pc上,请使用以下命令进行编译:
gcc *.c cJSON.c -lm
记得编译时末尾链接libm库。
熟悉使用cJSON库函数可从cJSON结构体入手,cJSON结构体如下所示:
typedef struct cJSON { struct cJSON *next,*prev; struct cJSON *child; int type; char *valuestring; int valueint; double valuedouble; char *string; } cJSON;
几点说明
cJSON作为Json格式的解析库,其主要功能无非就是构建和解析Json格式了,用途就是一端将要发送的数据已cjson形式封装,然后发送,另一端收到此数据后,还是按cjson形式解析,就得到想要的数据了。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include"cJSON.h" int main() { cJSON * usr; cJSON *arry; usr=cJSON_CreateObject(); //创建根数据对象 cJSON_AddStringToObject(usr,"name","fengxin"); //加入键值,加字符串 cJSON_AddStringToObject(usr,"passwd","123"); cJSON_AddNumberToObject(usr,"num",1); //加整数 char *out = cJSON_Print(usr); //将json形式打印成正常字符串形式 printf("%s\n",out); // 释放内存 cJSON_Delete(usr); free(out); }
运行结果:
{ "name": "fengxin", "passwd": "123", "num": 1 }
若干说明
4. 因为函数内部封装有malloc函数,所以使用free函数释放被out占用的内存空间
<2> 创建一个数组,并向数组添加一个字符串和一个数字:
int create_js(void) { cJSON *root, *js_body; root = cJSON_CreateArray(); cJSON_AddItemToArray(root, cJSON_CreateString("Hello world")); cJSON_AddItemToArray(root, cJSON_CreateNumber(10)); { // char *s = cJSON_Print(root); char *s = cJSON_PrintUnformatted(root); if(s){ printf(" %s \n",s); free(s); } } if(root) cJSON_Delete(root); return 0; } int main(int argc, char **argv) { create_js(); return 0; }
运行结果:
["Hello world",10]
<3> 对象里面包括一个数组,数组里面包括对象,对象里面再添加一个字符串和一个数字:
int create_js(void) { cJSON *root, *js_body, *js_list; root = cJSON_CreateObject(); cJSON_AddItemToObject(root,"body", js_body = cJSON_CreateArray()); cJSON_AddItemToArray(js_body, js_list = cJSON_CreateObject()); cJSON_AddStringToObject(js_list,"name","fengxin"); cJSON_AddNumberToObject(js_list,"status",100); { // char *s = cJSON_Print(root); char *s = cJSON_PrintUnformatted(root); if(s){ printf(" %s \n",s); free(s); } } if(root) cJSON_Delete(root); return 0; } int main(int argc, char **argv) { create_js(); return 0; }
{"body":[{"name":"fengxin","status":100}]}<4>其他组合就依次类推,只要搞清楚父子关系即可。随便嵌套随便玩。不再贴了。
处理流程:
1, 先将普通的json串处理成json对象,也就是所谓的创建json root的过程,只有一行代码即可:
cJSON *root; root = cJSON_Parse(js_string);
2,开始拿关键字,但如果关键字还有父层或者祖层,那就需要先从父层开拿,所谓剥洋葱是也!
先说没有父层的:
out={\"name\":\"fengxin\",\"passwd\":\"123\",\"num\":1}
#include<stdio.h> #include<stdlib.h> #include<string.h> #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
需要注意的是: 上面的type 已经在cJSON.h里面定义好了,有自己的意义。如果是在严格的场所,应该先判定该 item的type,然后再考虑去拿值。
而如果有父层的话,无非就是接着向下拿就是了
3.处理这串数据:
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
{\"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; }5.如果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; }
微信扫码关注
更新实时通知