首先,要介绍一下什么是json格式。

一.JSON格式简述

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。(来自“开源中国”资料)。
cJSON从名字可知,整个项目都是以极标准的C来写的,意思说,可以跨各种平台使用了。cJSON是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器。
cJSON 开源项目位置:点击打开链接
更加详细的解释和示例请查看 http://www.json.org/ 主页。
cJSON,目前来说,就只有两个文件,一个cJSON.c 一个cJSON.h文件。使用的时候,自己创建好一个main.c文件后,将头文件include进去。
如果是在linux pc上,请使用以下命令进行编译:
gcc  *.c  cJSON.c    -lm

记得编译时末尾链接libm库。

二.JSON结构体
熟悉使用cJSON库函数可从cJSON结构体入手,cJSON结构体如下所示:
  1. typedef struct cJSON {
  2. struct cJSON *next,*prev;
  3. struct cJSON *child;
  4. int type;
  5. char *valuestring;
  6. int valueint;
  7. double valuedouble;
  8. char * string;
  9. } cJSON;

几点说明

1.cJOSN结构体为一个双向列表,并可通过child指针访问下一层。
2.type变量决定数据项类型(键的类型),数据项可以是字符串可以是整形,也可以是浮点型。如果是整形值的话可从valueint,如果是浮点型的话可从valuedouble取出,以此类推。
3.string可理解为节点的名称,综合此处的第2点可理解为“键”的名称。

cJSON作为Json格式的解析库,其主要功能无非就是构建和解析Json格式了,用途就是一端将要发送的数据已cjson形式封装,然后发送,另一端收到此数据后,还是按cjson形式解析,就得到想要的数据了。


三.封装成json形式
接下来直接通过几个例子代码,一一解析。
   
第一,创建json数据串。这数据串,可能是对象,也可能是数组,也可能是它们的各种组合,其中再加上一些键值对。有一点要先说明:它们的组合,符合父子继承格式--这也是json数据串的特点。
<1>创建一个对象,并向这个对象里添加字符串和整型键值:
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include"cJSON.h"
  5. int main()
  6. {
  7. cJSON * usr;
  8. cJSON *arry;
  9. usr=cJSON_CreateObject(); //创建根数据对象
  10. cJSON_AddStringToObject(usr, "name", "fengxin"); //加入键值,加字符串
  11. cJSON_AddStringToObject(usr, "passwd", "123");
  12. cJSON_AddNumberToObject(usr, "num", 1); //加整数
  13. char *out = cJSON_Print(usr); //将json形式打印成正常字符串形式
  14. printf( "%s\n",out);
  15. // 释放内存
  16. cJSON_Delete(usr);
  17. free(out);
  18. }

运行结果:
  1. {
  2. "name": "fengxin",
  3. "passwd": "123",
  4. "num": 1
  5. }

若干说明

1. cJSON_CreateObject函数可创建一个根数据项,之后便可向该根数据项中添加string或int等内容,返回的是一个 cJSON的指针,注意,在这个指针用完了以后,需要手工调用 cJSON_Delete(root); 进行内存回收。
2. cJSON_AddNumberToObject向节点中添加子节点,例如此处添加name节点,节点值为字符串"fengxin"
3. 需要注意的是  json 格式的数据,虽然也是一个字符串的样子,但这个时候还是无法当成普通的字符串进行使用,需要调用 cJSON_PrintUnformatted(root) 或者 cJSON_Print(root);来将json对象转换成普通的字符串,并且都是以该json对象的根为基点。两个API的区别即是:一个是没有格式的:也就是转换出的字符串中间不会有"\n" "\t"之类的东西存在,而cJSON_Print(root);打印出来是人看起来很舒服的格式。
4. 因为函数内部封装有malloc函数,所以使用free函数释放被out占用的内存空间
<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. printf( " %s \n",s);
  12. free(s);
  13. }
  14. }
  15. if(root)
  16. cJSON_Delete(root);
  17. return 0;
  18. }
  19. int main(int argc, char **argv)
  20. {
  21. create_js();
  22. return 0;
  23. }
运行结果:
["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", "fengxin");
  8. cJSON_AddNumberToObject(js_list, "status", 100);
  9. {
  10. // char *s = cJSON_Print(root);
  11. char *s = cJSON_PrintUnformatted(root);
  12. if(s){
  13. printf( " %s \n",s);
  14. free(s);
  15. }
  16. }
  17. if(root)
  18. cJSON_Delete(root);
  19. return 0;
  20. }
  21. int main(int argc, char **argv)
  22. {
  23. create_js();
  24. return 0;
  25. }
运行结果:
{"body":[{"name":"fengxin","status":100}]}

<4>其他组合就依次类推,只要搞清楚父子关系即可。随便嵌套随便玩。不再贴了。

四.解析json得到数据
解析数据包的过程和组装数据包的过程相反

处理流程:

1, 先将普通的json串处理成json对象,也就是所谓的创建json root的过程,只有一行代码即可:

  1. cJSON *root;
  2. root = cJSON_Parse(js_string);

2,开始拿关键字,但如果关键字还有父层或者祖层,那就需要先从父层开拿,所谓剥洋葱是也!

先说没有父层的:

out={\"name\":\"fengxin\",\"passwd\":\"123\",\"num\":1}
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include"cJSON.h"
  5. int main()
  6. {
  7. cJSON *json,*json_name,*json_passwd,*json_num;
  8. char* out= "{\"name\":\"fengxin\",\"passwd\":\"123\",\"num\":1}";
  9. json = cJSON_Parse(out); //解析成json形式
  10. json_name = cJSON_GetObjectItem( json , "name" ); //获取键值内容
  11. json_passwd = cJSON_GetObjectItem( json , "passwd" );
  12. json_num = cJSON_GetObjectItem( json , "num" );
  13. printf( "name:%s,passwd:%s,num:%d\n",json_name->valuestring,json_passwd->valuestring,json_num->valueint);
  14. cJSON_Delete(json); //释放内存
  15. free(out);
  16. }

显示结果:

name:fengxin,passwd:123,num:1

需要注意的是: 上面的type 已经在cJSON.h里面定义好了,有自己的意义。如果是在严格的场所,应该先判定该 item的type,然后再考虑去拿值。

而如果有父层的话,无非就是接着向下拿就是了

3. 处理这串数据:

out={\"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. cJSON *js_list = cJSON_GetObjectItem(root, "list");
  8. if(!js_list) {
  9. printf( "no list!\n");
  10. return -1;
  11. }
  12. printf( "list type is %d\n",js_list->type);
  13. cJSON *name = cJSON_GetObjectItem(js_list, "name");
  14. if(!name) {
  15. printf( "No name !\n");
  16. return -1;
  17. }
  18. printf( "name type is %d\n",name->type);
  19. printf( "name is %s\n",name->valuestring);
  20. cJSON *age = cJSON_GetObjectItem(js_list, "age");
  21. if(!age) {
  22. printf( "no age!\n");
  23. return -1;
  24. }
  25. printf( "age type is %d\n", age->type);
  26. printf( "age is %d\n",age->valueint);
  27. cJSON *js_other = cJSON_GetObjectItem(root, "other");
  28. if(!js_other) {
  29. printf( "no list!\n");
  30. return -1;
  31. }
  32. printf( "list type is %d\n",js_other->type);
  33. cJSON *js_name = cJSON_GetObjectItem(js_other, "name");
  34. if(!js_name) {
  35. printf( "No name !\n");
  36. return -1;
  37. }
  38. printf( "name type is %d\n",js_name->type);
  39. printf( "name is %s\n",js_name->valuestring);
  40. if(root)
  41. cJSON_Delete(root);
  42. 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
所谓子子孙孙无穷尽也,按照上面那个方法推下去即可。
4.json 里数组怎么取?
{\"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. if(root)
  24. cJSON_Delete(root);
  25. return 0;
  26. }

5. 如果json数组里面又搞了对象怎么办?

不怕搞对象,就怕这样搞对象? 无他,就是稍微复杂了一点,全是体力活儿:

<1> 既然是数组里面,那肯定要先测量数组的大小,然后根据大小循环拿;

<2> 拿到一个数组项,然后把这个项先转化成普通的json字符串,也就是 char *s 能接受的。

<3>再次将这个json字符串,转化成一个json对象

<4> 按照拿普通对象中的东西那样开干就行了。

{\"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. if(root)
  34. cJSON_Delete(root);
  35. return 0;
  36. }

CJSON 使用介绍相关推荐

  1. CJSON的介绍以及使用

    一.JSON概述 1.1 JSON介绍 JSON:JavaScript对象表示法(JavaScript Object Notation).是一种轻量级的数据交换格式.它基于ECMAScript的一个子 ...

  2. cJSON库用法详解

    cJSON库用法详解_宁静致远2021的博客-CSDN博客_cjson cJSON库用法详解 问题和需要注意的地方 一.JSON.cJSON简介 1. JSON 简介 2. JSON 语法 3. 开源 ...

  3. 【C】cJSON使用以及在stm32中的应用

    1. cJSON使用 最近一段时间在整理自己进入研究生阶段后学习过程中的一些内容,之前在进行相关代码调试过程中,也的确耗费了比较大的精力去搜寻资料,然后整合代码到自己所需要的系统中,如在stm32中使 ...

  4. c语言组json包,json格式解析和libjson的用法介绍(关于cjson的使用方法)

    在阅读本文之前,请先阅读下<Rss Reader实例开发之系统设计>一文. Rss Reader实例开发中,进行网络数据交换时主要使用到了两种数据格式:JSON与XML.本文主要介绍JSO ...

  5. cjson源代码解读 (一)介绍

    cjson是一个非常小巧的c语言写的json解析器, 代码比较短小精悍, c文件不过千行, 同类代码可在网页 json库  中找到.  项目地址如下: cjson地址 json的格式就不介绍了,  下 ...

  6. cJSON介绍及使用

    JSON(JavaScript Object Notation)是一种轻量级的文本数据交换格式,易于让人阅读.同时也易于机器解析和生成.尽管JSON是Javascript的一个子集,但JSON是独立于 ...

  7. 第三方库介绍——cJSON库

    文章目录 综述 API cJSON结构体 数据的封装 Json 对象操作 Json 数组操作 序列化 Json 字符串的解析 内存释放 Json 数据的封装 Json 对象操作举例 Json 数组操作 ...

  8. ​Openresty最佳案例 | 第8篇:RBAC介绍、sql和redis模块工具类

    RBAC介绍 RBAC(Role-Based Access Control,基于角色的访问控制),用户基于角色的访问权限控制.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成&q ...

  9. libevent和libcurl实现http和https服务器 cJSON使用

    前言 libevent和libcurl都是功能强大的开源库:libevent主要实现服务器,包含了select.epoll等高并发的实现:libcurl实现了curl命令的API封装,主要作为客户端. ...

最新文章

  1. POJ1422 最小路径覆盖
  2. 什么技术能改变世界?
  3. 资讯类产品的数据驱动增长方法论
  4. linux文件的打包与下载总结,linux下文件的打包和压缩
  5. BOMHEAD display issue
  6. ibatis mysql 同时删多个表报错_MySQL中Multiple primary key defined报错的解决办法
  7. 太长的sql怎么分析_因为ESR, 我一定要推荐你这款 SQL 神器
  8. 2063:【例1.4】牛吃牧草【入门题】
  9. 在用户空间加载和卸载驱动
  10. 用VMWARE学习组网(二)
  11. 邮件服务器向hotmail等邮箱发信收到退信的解决方法
  12. 【使用工具和软件汇总】
  13. C#Json数据交互
  14. matlab 生成噪声信号
  15. 超强Commodore C64 emulator for Flash Player 9
  16. QT将英文星期转为中文星期
  17. 解决git Please use -- (and optionally --no-guess) to disambiguate
  18. jQuery:等页面DOM加载完毕后再执行代码
  19. 《五种时间:重建人生秩序》读书笔记
  20. HTML5学习(二)---构造网页

热门文章

  1. icp光谱仪的工作原理_ICP2060T ICP光谱仪工作原理
  2. Ps中的钢笔工具和快速选择工具
  3. Oracle 服务器连不上解决方式(远程telnet 1521端口失败)
  4. 马尔科夫链Markov以及空间Markov Matlab代码
  5. C++ scanf()函数
  6. Ubuntu中使用RoboMongo实现MongoDB的可视化
  7. 关于全概率和贝叶斯公式的使用场景说明
  8. trunk vlan pvid 学习实验整理 2
  9. ifconfig 使用
  10. 我支持刘翔,理由有三