微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

【cJSon】cJSON学习笔记

转载地址:http://blog.csdn.net/dengjin20104042056/article/details/47831011

1.JSON格式简述

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C,C++,C#,Java,JavaScript,Perl,Python等)。这些特性使JSON成为理想的数据交换语言。
cJSON一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器。
接触yeelink平台之后,慢慢接触到JSON格式,虽然一些简单的情况可以通过string库函数解析和组装JSON数据包,但是若有cJSON库的帮助,解析和组装JSON数据包的工作便会变得简单的多,下面就从两个例子出发说明cJSON数据包的使用方法

2.JSON结构体

熟悉使用cJSON库函数可从cJSON结构体入手,cJSON结构体如下所示:
  1. typedefstructcJSON{
  2. structcJSON*next,*prev;
  3. structcJSON*child;
  4. inttype;
  5. char*valuestring;
  6. intvalueint;
  7. doublevaluedouble;
  8. char*string;
  9. }cJSON;
cJSon类型
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6

#define cJSON_IsReference 256
#define cJSON_StringIsConst 512

说明

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

3.解析JSON数据包

例如在QCA平台中读取一个开关量的结果,向QCA平台请求之后可以获得以下JSON数据包:
{"timestamp":"2013-11-19T08:50:11","value":1}
在这个JSON数据包中有两个数据项(键值对),一个是时间戳,该时间戳为字符串形式;另一个是开关值,该开关值为整型。该例子主要用于模拟向QCA平台请求开关量数据。

参考代码

    #include<stdio.h>
  1. #include<stdlib.h>
  2. #include"cJSON.h"
  3. //被解析的JSON数据包
  4. chartext[]="{\"timestamp\":\"2013-11-19T08:50:11\",\"value\":1}";
  5. intmain(intargc,constchar*argv[])
  6. {
  7. cJSON*json,*json_value,*json_timestamp;
  8. //解析数据包
  9. json=cJSON_Parse(text);
  10. if(!json)
  11. {
  12. printf("Errorbefore:[%s]\n",cJSON_GetErrorPtr());
  13. }
  14. else
  15. //解析开关值
  16. json_value=cJSON_GetobjectItem(json,"value");
  17. if(json_value->type==cJSON_Number)
  18. //从valueint中获得结果
  19. printf("value:%d\r\n",json_value->valueint);
  20. }
  21. //解析时间戳
  22. json_timestamp=cJSON_GetobjectItem(json,"timestamp");
  23. if(json_timestamp->type==cJSON_String)
  24. //valuestring中获得结果
  25. printf("%s\r\n",json_timestamp->valuestring);
  26. //释放内存空间
  27. cJSON_Delete(json);
  28. return0;
  29. }

运行结果

value:1
2013-11-19T08:50:11

若干说明

1.cJSON_Parse函数负责解析JSON数据包,并按照cJSON结构体的结构序列化整个数据包。使用该函数会通过malloc函数在内存中开辟一个空间,使用完成需要手动释放。
2.cJSON_GetobjectItem函数可从cJSON结构体中查找某个子节点名称(键名称),如果查找成功可把该子节点序列化到cJSON结构体中。
3.如果需要使用cJSON结构体中的内容,可通过cJSON结构体中的valueint和valuestring取出有价值的内容(即键的值)
4.可通过cJSON_Delete释放内存空间。
4.组装JSON数据包
组装数据包的过程和解析数据包的过程相反,下面的例子描述如何组装以下数据包,该数据包只有一个数据项(键值对)。该例子主要用于模拟向QCA平台上传传感器数据。
{
"value": 123.400000
}
    //创建JSONObject
  1. cJSON*root=cJSON_CreateObject();
  2. //加入节点(键值对),节点名称为value,节点值为123.4
  3. cJSON_AddNumberToObject(root,"value",123.4);
  4. //打印JSON数据包
  5. char*out=cJSON_Print(root);
  6. printf("%s\n",out);
  7. //释放内存
  8. cJSON_Delete(root);
  9. free(out);
  10. 1.cJSON_CreateObject函数可创建一个根数据项,之后便可向该根数据项中添加string或int等内容
2. cJSON_AddNumberToObject向节点中添加子节点,例如此处添加value节点,节点值为123.4
3. cJSON_Print函数可以打印根数据项,加入制表符换行符等标识符使得JSON数据包更易阅读
4. 使用free函数释放被out占用的内存空间

1.重要函数说明
【1】两个创建
【创建JSON对象】cJSON *cJSON_CreateObject(void);
【创建JSON数组】cJSON *cJSON_CreateArray(void);

【2】两种添加
【向对象中添加】void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
【向数组中添加】void cJSON_AddItemToArray(cJSON *array,85); line-height: 35px; font-family: Tahoma; font-size: 18px;">
【3】常用几招
【向对象中增加数字】cJSON_AddItemToObject(root,"value",cJSON_CreateNumber(value));
【向对象中增加文件】cJSON_AddItemToObject(root,"string",cJSON_CreateString(string));
【4】JSON嵌套
【向对象中增加数组】cJSON_AddItemToObject(root,"rows",rows = cJSON_CreateArray());
【向数组中增加对象】cJSON_AddItemToArray(rows,row = cJSON_CreateObject());
2.创建各种各样的JSON数据包
在这里通过代码举几个例子,更多的内容请查看代码仓库中的相关文件。
【1】JSON数字
  1. voidcreate_single_number(void){
  2. cJSON*root;
  3. char*out;
  4. intvalue=24;
  5. root=cJSON_CreateObject();//创建根
  6. cJSON_AddItemToObject(root,cJSON_CreateNumber(value));
  7. //打印并释放
  8. out=cJSON_Print(root);cJSON_Delete(root);printf("%s\n",out);free(out);
  9. //控制台输出
  10. #if0
  11. {
  12. "value":24
  13. }
  14. #endif
  15. }
【简单说明】
【1】cJSON_AddItemToObject(root,cJSON_CreateNumber(value));
【2】cJSON_AddNumberToObject(root,value);
【1】和【2】效果完全相同。
【2】JSON字符串
    voidcreate_single_string(char*name="xukai871105";
  1. //方法使用cJSON_AddItemToObject,推荐使用
  2. "name",cJSON_CreateString(name));
  3. "name":"xukai871105"
  4. 【2】 cJSON_AddStringToObject(root,name);
    【3】JSON布尔类型
    voidcreate_bool(root=cJSON_CreateObject();//创建根
  1. cJSON_AddItemToObject(root,"success",cJSON_CreateFalse());
  2. //打印并释放
  3. out=cJSON_Print(root);cJSON_Delete(root);printf("%s\n",out);free(out);
  4. //控制台输出
  5. #if0
  6. {
  7. "success":false
  8. }
  9. #endif
  10. }
【1】布尔类型不需要加引号。
3.JSON格式嵌套
JSON格式在使用时往往存在嵌套,例如JSON对象中嵌套JSON数组而JSON数组中嵌套JSON对象,下面就通过几个简单的例子说明问题。
【1】JSON简单嵌套
    voidcreate_simple(intlist[4]={5,6,7,8};
  1. "lists",cJSON_CreateIntArray(list,4));
  2. "lists":[5,8]
  3. 【2】JSON复杂嵌套
      voidcreate_complex(cJSON*root,*rows,*row;
    1. inti=0;
    2. char*title[3]={"树莓派学习笔记——索引博文",
    3. "树莓派学习笔记——GPIO功能学习",
    4. "物联网学习笔记——索引博文"};
    5. char*url[3]={"http://blog.csdn.net/xukai871105/article/details/23115627",248);">"http://blog.csdn.net/xukai871105/article/details/12684617",108); border-left-width: 3px;">"http://blog.csdn.net/xukai871105/article/details/23366187"};
    6. cJSON_AddNumberToObject(root,"total",3);
    7. //在object中加入array
    8. "rows",rows=cJSON_CreateArray());
    9. for(i=0;i<3;i++){
    10. //在array中加入object
    11. cJSON_AddItemToArray(rows,row=cJSON_CreateObject());
    12. cJSON_AddItemToObject(row,"title",cJSON_CreateString(title[i]));
    13. cJSON_AddItemToObject(row,"url",cJSON_CreateString(url[i]));
    14. "total":3,108); border-left-width: 3px;">"rows":[{
    15. "title":"树莓派学习笔记——索引博文",108); border-left-width: 3px;">"url":"http://blog.csdn.net/xukai871105/article/details/23115627"
    16. },{
    17. "title":"树莓派学习笔记——GPIO功能学习",248);">"url":"http://blog.csdn.net/xukai871105/article/details/12684617"
    18. },{
    19. "title":"物联网学习笔记——索引博文",108); border-left-width: 3px;">"url":"http://blog.csdn.net/xukai871105/article/details/23366187"
    20. }]
    21. rows为JSON对象,rows对象中嵌套JSON数组,每一个JSON数组的元素又是一个JSON对象,该该对象名为row,row对象中具有两个键值对,分别是titile和url。
      2015/08/19 17:50

      【其他参考示例】

      1. 函数的使用

      宏的定义原型:
      /* Macros for creating things quickly. */
      #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object,name,cJSON_CreateNull())
      #define cJSON_AddTruetoObject(object,cJSON_CreateTrue())
      #define cJSON_AddFalsetoObject(object,cJSON_CreateFalse())
      #define cJSON_AddBoolToObject(object,b) cJSON_AddItemToObject(object,cJSON_CreateBool(b))
      #define cJSON_AddNumberToObject(object,n) cJSON_AddItemToObject(object,cJSON_CreateNumber(n))
      #define cJSON_AddStringToObject(object,s) cJSON_AddItemToObject(object,cJSON_CreateString(s))

      示例:
      cJSON *root = cJSON_CreateObject(); //先创建一个对象
      cJSON_AddNumberToObject(root,123.4);
      cJSON_AddStringToObject(root,"year","2015");
      cJSON_AddNullToObject(root,"secret");
      cJSON_AddTruetoObject(root,"Bool");
      cJSON_AddFalsetoObject(root,"false");
      cJSON_AddBoolToObject(root,"Yes",3);
      cJSON_AddBoolToObject(root,0);
      out = cJSON_Print(root); //打印对象
      //out = cJSON_PrintUnformatted(root); //非格式化的打印
      //printf("===> 2: %s\n",out);
      printf("%s\n",out);
      cJSON_Delete(root); //释放对象所占的内存
      free(out);

      函数的原型:
      /* These calls create a cJSON item of the appropriate type. */
      extern cJSON *cJSON_CreateNull(void);
      extern cJSON *cJSON_CreateTrue(void);
      extern cJSON *cJSON_CreateFalse(void);
      extern cJSON *cJSON_CreateBool(int b);
      extern cJSON *cJSON_CreateNumber(double num);
      extern cJSON *cJSON_CreateString(const char *string);
      extern cJSON *cJSON_CreateArray(void);
      extern cJSON *cJSON_CreateObject(void);

      示例:参考上面博客代码

      函数原型:
      /* These utilities create an Array of count items. */
      extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
      extern cJSON *cJSON_CreateFloatArray(const float *numbers,212);">extern cJSON *cJSON_CreateDoubleArray(const double *numbers,212);">extern cJSON *cJSON_CreateStringArray(const char **strings,212);">
      /* Append item to the specified array/object. */
      extern void cJSON_AddItemToArray(cJSON *array,cJSON *item);
      extern void cJSON_AddItemToObject(cJSON *object,212);">extern void cJSON_AddItemToObjectCS(cJSON *object,cJSON *item);

      示例:
      char *out = NULL;
      int array[] = {1,2,3,4};
      int array1[] = {1,4,5,6};
      cJSON *json = NULL;
      cJSON *item = NULL;
      cJSON *tmp = NULL;

      json = cJSON_CreateObject();
      //cJSON_AddItemToObject(json,"array",cJSON_CreateIntArray(array,4)); //与下面两行等价
      item = cJSON_CreateIntArray(array,4);
      cJSON_AddItemToObject(json,item);
      out = cJSON_Print(json);
      printf("%s\n",out);

      printf("=========================\n");
      printf("size: %d\n",cJSON_GetArraySize(item)); //输出为4 4个元素

      tmp = cJSON_GetArrayItem(json,0); //获取json中的第一个节点
      if (NULL != tmp)
      {
      printf("ok..\n");
      printf("size: %d\n",cJSON_GetArraySize(tmp));
      }
      else
      printf("error...\n");

      //此时item数组中的元素有 1 2 3 4 5 6 7
      printf("=========================\n");
      cJSON_AddItemToArray(item,cJSON_CreateNumber(5));
      cJSON_AddItemToArray(item,cJSON_CreateNumber(6));
      cJSON_AddItemToArray(item,cJSON_CreateNumber(7));
      printf("size: %d\n",cJSON_GetArraySize(item));
      out = cJSON_Print(json);
      printf("%s\n",out);

      tmp = cJSON_CreateIntArray(array1,6);
      //cJSON_AddItemToObject(json,"array1",tmp); //好像与下面一句话等价呢
      cJSON_AddItemReferencetoObject(json,tmp);
      out = cJSON_Print(json);
      printf("%s\n",out);


      //整形数组的参考示例
      int array3[] = {1,9};
      json = cJSON_CreateIntArray(array3,5);
      out = cJSON_Print(json); cJSON_Delete(json); printf("%s\n",out); free(out);

      //字符指针数组
      const char *strings[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
      json = cJSON_CreateStringArray(strings,7);
      out = cJSON_Print(json); cJSON_Delete(json); printf("%s\n",out); free(out);

      5.总结
      整体来说cJSON简单易用,解决了JSON数据包解析和组装的问题,几乎就掌握了CJSON。

      版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

      相关推荐