C/C++程序开发: cJSON的使用(创建与解析JSON数据)

举报
DS小龙哥 发表于 2021/12/09 23:59:32 2021/12/09
【摘要】 一、cJSON介绍       cJSON 是一个超轻巧,携带方便,单文件,可以作为 ANSI-C 标准的 JSON 解析器,是一个用C语言编写的简单好用的JSON解析器;它只包含一个C文件和一个头文件,可以非常容易集成到自己工程项目中。         并且cJ...

一、cJSON介绍

      cJSON 是一个超轻巧,携带方便,单文件,可以作为 ANSI-C 标准的 JSON 解析器,是一个用C语言编写的简单好用的JSON解析器;它只包含一个C文件和一个头文件,可以非常容易集成到自己工程项目中。

        并且cJSON是用ANSI C(C89)编写的,可以兼容所有支持C语言的平台和编译器。

        cJSON下载地址:  cJSON download | SourceForge.nethttps://sourceforge.net/projects/cjson/

       cJSON的GitHub仓库地址:
https://github.com/DaveGamble/cJSONhttps://github.com/DaveGamble/cJSON

二、JSON简介、语法介绍 

2.1 JSON是什么? 

    JSON是JavaScript Object Notation(JavaScript对象表示法),是一种轻量级的数据交换格式。     

    JSON主要是用来存储和交换文本信息,类似XML格式;但是JSON比XML更小、更快,更易解析。

    JSON是基于ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。

       简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。 比如: Web服务器接口基本都是采用JSON反馈数据,采用JSON格式字符串来描述符信息。 JSON文件的后缀一般是.json,这个只是为了方便辨识。

   简单的说,JSON就是按照指定格式序列化的字符串,就算不使用任何现成的解析库,自己也可以按照正常解析字符串的思路去解析;有现成的标准JSON解析库,那就大大减轻了我们的工作量。   

   JSON格式的数据示例:  这是表示当前时间的JSON字符串


  
  1. {
  2. "success": "1",
  3. "result": {
  4. "timestamp": "1631849514",
  5. "datetime_1": "2021-09-17 20:31:54",
  6. "datetime_2": "2021年09月17日 20时31分54秒",
  7. "week_1": "5",
  8. "week_2": "星期五",
  9. "week_3": "周五",
  10. "week_4": "Friday"
  11. }
  12. }

   JSON格式的数据示例:  这是表示未来几天天气预报的json字符串


  
  1. {
  2. "success": "1",
  3. "result": [
  4. {
  5. "weaid": "1",
  6. "days": "2021-09-17",
  7. "week": "星期五",
  8. "cityno": "beijing",
  9. "citynm": "北京",
  10. "cityid": "101010100",
  11. "temperature": "26℃/17℃",
  12. "humidity": "0%/0%",
  13. "weather": "晴",
  14. "weather_icon": "http://api.k780.com/upload/weather/d/0.gif",
  15. "weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
  16. "wind": "北风转西南风",
  17. "winp": "小于3级",
  18. "temp_high": "26",
  19. "temp_low": "17",
  20. "humi_high": "0",
  21. "humi_low": "0",
  22. "weatid": "1",
  23. "weatid1": "1",
  24. "windid": "8",
  25. "winpid": "0",
  26. "weather_iconid": "0",
  27. "weather_iconid1": "0"
  28. },
  29. {
  30. "weaid": "1",
  31. "days": "2021-09-18",
  32. "week": "星期六",
  33. "cityno": "beijing",
  34. "citynm": "北京",
  35. "cityid": "101010100",
  36. "temperature": "25℃/17℃",
  37. "humidity": "0%/0%",
  38. "weather": "多云",
  39. "weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
  40. "weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
  41. "wind": "西南风",
  42. "winp": "小于3级",
  43. "temp_high": "25",
  44. "temp_low": "17",
  45. "humi_high": "0",
  46. "humi_low": "0",
  47. "weatid": "2",
  48. "weatid1": "2",
  49. "windid": "5",
  50. "winpid": "0",
  51. "weather_iconid": "1",
  52. "weather_iconid1": "1"
  53. },
  54. {
  55. "weaid": "1",
  56. "days": "2021-09-19",
  57. "week": "星期日",
  58. "cityno": "beijing",
  59. "citynm": "北京",
  60. "cityid": "101010100",
  61. "temperature": "19℃/15℃",
  62. "humidity": "0%/0%",
  63. "weather": "小雨转中雨",
  64. "weather_icon": "http://api.k780.com/upload/weather/d/7.gif",
  65. "weather_icon1": "http://api.k780.com/upload/weather/n/8.gif",
  66. "wind": "西南风转北风",
  67. "winp": "小于3级转小于3级",
  68. "temp_high": "19",
  69. "temp_low": "15",
  70. "humi_high": "0",
  71. "humi_low": "0",
  72. "weatid": "8",
  73. "weatid1": "9",
  74. "windid": "5",
  75. "winpid": "0",
  76. "weather_iconid": "7",
  77. "weather_iconid1": "8"
  78. },
  79. {
  80. "weaid": "1",
  81. "days": "2021-09-20",
  82. "week": "星期一",
  83. "cityno": "beijing",
  84. "citynm": "北京",
  85. "cityid": "101010100",
  86. "temperature": "26℃/16℃",
  87. "humidity": "0%/0%",
  88. "weather": "多云转晴",
  89. "weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
  90. "weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
  91. "wind": "北风",
  92. "winp": "3-4级转3-4级",
  93. "temp_high": "26",
  94. "temp_low": "16",
  95. "humi_high": "0",
  96. "humi_low": "0",
  97. "weatid": "2",
  98. "weatid1": "1",
  99. "windid": "8",
  100. "winpid": "1",
  101. "weather_iconid": "1",
  102. "weather_iconid1": "0"
  103. },
  104. {
  105. "weaid": "1",
  106. "days": "2021-09-21",
  107. "week": "星期二",
  108. "cityno": "beijing",
  109. "citynm": "北京",
  110. "cityid": "101010100",
  111. "temperature": "27℃/16℃",
  112. "humidity": "0%/0%",
  113. "weather": "晴",
  114. "weather_icon": "http://api.k780.com/upload/weather/d/0.gif",
  115. "weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
  116. "wind": "西北风转北风",
  117. "winp": "小于3级",
  118. "temp_high": "27",
  119. "temp_low": "16",
  120. "humi_high": "0",
  121. "humi_low": "0",
  122. "weatid": "1",
  123. "weatid1": "1",
  124. "windid": "7",
  125. "winpid": "0",
  126. "weather_iconid": "0",
  127. "weather_iconid1": "0"
  128. },
  129. {
  130. "weaid": "1",
  131. "days": "2021-09-22",
  132. "week": "星期三",
  133. "cityno": "beijing",
  134. "citynm": "北京",
  135. "cityid": "101010100",
  136. "temperature": "26℃/18℃",
  137. "humidity": "0%/0%",
  138. "weather": "多云",
  139. "weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
  140. "weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
  141. "wind": "北风转东北风",
  142. "winp": "小于3级",
  143. "temp_high": "26",
  144. "temp_low": "18",
  145. "humi_high": "0",
  146. "humi_low": "0",
  147. "weatid": "2",
  148. "weatid1": "2",
  149. "windid": "8",
  150. "winpid": "0",
  151. "weather_iconid": "1",
  152. "weather_iconid1": "1"
  153. },
  154. {
  155. "weaid": "1",
  156. "days": "2021-09-23",
  157. "week": "星期四",
  158. "cityno": "beijing",
  159. "citynm": "北京",
  160. "cityid": "101010100",
  161. "temperature": "24℃/16℃",
  162. "humidity": "0%/0%",
  163. "weather": "多云",
  164. "weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
  165. "weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
  166. "wind": "东北风",
  167. "winp": "小于3级",
  168. "temp_high": "24",
  169. "temp_low": "16",
  170. "humi_high": "0",
  171. "humi_low": "0",
  172. "weatid": "2",
  173. "weatid1": "2",
  174. "windid": "1",
  175. "winpid": "0",
  176. "weather_iconid": "1",
  177. "weather_iconid1": "1"
  178. }
  179. ]
  180. }

2.2  JSON语法介绍

JSON里就分为两种结构:  对象和数组,通过这两种结构可以表示各种复杂的结构。

JSON语法规则
1. 大括号 { } 用来保存对象
2. 中括号 [ ] 用来保存数组,数组里也可以包含多个对象,对象里又可以包含数组,可以嵌套
3. JSON的值表示语法:  key : value   -->   "width": 1280
4. 多个数据由逗号分隔:  {"width": 1920,"height": 1080}

JSON值可以是以下几种类型:
1. 数字(整数或浮点数)  
2. 字符串(在双引号中)
3. 逻辑值(true 或 false)
4. 数组(在中括号中)
5. 对象(在大括号中)
6. null (空值)

三、cJSON创建简单JSON数据并解析

3.1 新建工程

这是下载下来的cJSON源文件,将它加到自己工程中即可。

 我这里使用VS2017建立工程,演示实例。

建好工程之后,将文件添加到工程里:

在VS2017里使用C语言的字符串处理函数会报错,提示不安全;

1>d:\linux-share-dir\vs2017\console_cjsontest\console_cjsontest\cjson.c(155): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

解决办法是:找到【项目属性】,点击【C++】里的【预处理器】,对【预处理器】进行编辑,在里面加入一段代码:_CRT_SECURE_NO_WARNINGS。

3.2 创建JSON数据 

 接下来目标是使用cJSON创建出下面这样一个JSON格式数据:


  
  1. {
  2. "text": "我是一个字符串数据",
  3. "number": 666,
  4. "state1": false,
  5. "state2": true,
  6. "state3": null
  7. }

 示例代码如下:


  
  1. #include <iostream>
  2. //因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
  3. extern "C" {
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "cJSON.h"
  7. }
  8. int main()
  9. {
  10. //1. 创建cJSON对象
  11. cJSON* root = cJSON_CreateObject();
  12. //2. 创建数据
  13. cJSON_AddStringToObject(root, "text","我是一个字符串数据");
  14. cJSON_AddNumberToObject(root,"number",666);
  15. cJSON_AddBoolToObject(root, "state1", cJSON_False);
  16. cJSON_AddBoolToObject(root, "state2", cJSON_True);
  17. cJSON_AddNullToObject(root, "state3");
  18. //3. 打印生成的结果
  19. char *json_data=cJSON_PrintUnformatted(root);
  20. printf("%s\n",json_data);
  21. //4. 释放空间
  22. cJSON_Delete(root);
  23. return 0;
  24. }

3.3 解析JSON数据 


  
  1. #include <iostream>
  2. //因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
  3. extern "C" {
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "cJSON.h"
  7. }
  8. //将要解析的JSON数据.
  9. char data[] =
  10. "{"
  11. "\"text\": \"我是一个字符串数据\","
  12. "\"number\" : 666,"
  13. "\"state1\" : false,"
  14. "\"state2\" : true,"
  15. "\"state3\" : null"
  16. "}";
  17. int main()
  18. {
  19. //1. 载入JSON数据
  20. cJSON* root = cJSON_Parse(data);
  21. if (root == NULL)return 0;
  22. //2. 解析字段
  23. cJSON* item;
  24. item=cJSON_GetObjectItem(root,"text");
  25. if (item)
  26. {
  27. printf("text=%s\n",item->valuestring);
  28. }
  29. item = cJSON_GetObjectItem(root, "number");
  30. if (item)
  31. {
  32. printf("text=%d\n", item->valueint);
  33. }
  34. item = cJSON_GetObjectItem(root, "state1");
  35. if (item)
  36. {
  37. printf("state1=%d\n", item->valueint);
  38. }
  39. item = cJSON_GetObjectItem(root, "state2");
  40. if (item)
  41. {
  42. printf("state2=%d\n", item->valueint);
  43. }
  44. item = cJSON_GetObjectItem(root, "state3");
  45. if (item)
  46. {
  47. printf("state3=%d\n", item->valueint);
  48. }
  49. //3. 释放空间
  50. cJSON_Delete(root);
  51. return 0;
  52. }

 四、cJSON创建嵌套的对象数据

 目标: 使用cJSON创建出下面这样一个JSON格式数据


  
  1. {
  2. "data1": {
  3. "text": "我是一个字符串数据1",
  4. "number": 666,
  5. "state1": false,
  6. "state2": true,
  7. "state3": null
  8. },
  9. "data2": {
  10. "text": "我是一个字符串数据2",
  11. "number": 666,
  12. "state1": false,
  13. "state2": true,
  14. "state3": null
  15. }
  16. }

4.1 创建json数据


  
  1. #include <iostream>
  2. //因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
  3. extern "C" {
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "cJSON.h"
  7. }
  8. int main()
  9. {
  10. //1. 创建cJSON对象
  11. cJSON* root = cJSON_CreateObject();
  12. //2. 创建对象数据1
  13. cJSON* item1 = cJSON_CreateObject();
  14. cJSON_AddStringToObject(item1, "text","我是一个字符串数据1");
  15. cJSON_AddNumberToObject(item1,"number",666);
  16. cJSON_AddBoolToObject(item1, "state1", cJSON_False);
  17. cJSON_AddBoolToObject(item1, "state2", cJSON_True);
  18. cJSON_AddNullToObject(item1, "state3");
  19. cJSON_AddItemToObject(root, "data1", item1);
  20. //3. 创建对象数据2
  21. cJSON* item2 = cJSON_CreateObject();
  22. cJSON_AddStringToObject(item2, "text", "我是一个字符串数据2");
  23. cJSON_AddNumberToObject(item2, "number", 666);
  24. cJSON_AddBoolToObject(item2, "state1", cJSON_False);
  25. cJSON_AddBoolToObject(item2, "state2", cJSON_True);
  26. cJSON_AddNullToObject(item2, "state3");
  27. cJSON_AddItemToObject(root, "data2", item2);
  28. //3. 打印生成的结果
  29. char *json_data=cJSON_PrintUnformatted(root);
  30. printf("%s\n",json_data);
  31. //4. 释放空间
  32. cJSON_Delete(root);
  33. return 0;
  34. }

4.2 解析JSON数据


  
  1. #include <iostream>
  2. //因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
  3. extern "C" {
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "cJSON.h"
  7. }
  8. //将要解析的JSON数据.
  9. char data[] =
  10. "{"
  11. "\"data1\": {"
  12. "\"text\": \"我是一个字符串数据1\","
  13. "\"number\" : 666,"
  14. "\"state1\" : false,"
  15. "\"state2\" : true,"
  16. "\"state3\" : null"
  17. "},"
  18. "\"data2\": {"
  19. "\"text\":\"我是一个字符串数据2\","
  20. "\"number\" : 666,"
  21. "\"state1\" : false,"
  22. "\"state2\" : true,"
  23. "\"state3\" : null"
  24. "}"
  25. "}";
  26. int main()
  27. {
  28. //1. 载入JSON数据
  29. cJSON* root = cJSON_Parse(data);
  30. if (root == NULL)return 0;
  31. //2. 解析字段
  32. cJSON* item;
  33. item=cJSON_GetObjectItem(root,"data1");
  34. if (item)
  35. {
  36. cJSON *obj;
  37. obj=cJSON_GetObjectItem(item, "text");
  38. if (obj)
  39. {
  40. printf("text=%s\n", obj->valuestring);
  41. }
  42. obj=cJSON_GetObjectItem(item, "number");
  43. if (obj)
  44. {
  45. printf("number=%d\n", obj->valueint);
  46. }
  47. obj = cJSON_GetObjectItem(item, "state1");
  48. if (obj)
  49. {
  50. printf("state1=%d\n", obj->valueint);
  51. }
  52. obj = cJSON_GetObjectItem(item, "state2");
  53. if (obj)
  54. {
  55. printf("state2=%d\n", obj->valueint);
  56. }
  57. obj = cJSON_GetObjectItem(item, "state3");
  58. if (obj)
  59. {
  60. printf("state3=%d\n", obj->valueint);
  61. }
  62. }
  63. item = cJSON_GetObjectItem(root, "data2");
  64. if (item)
  65. {
  66. cJSON *obj;
  67. obj = cJSON_GetObjectItem(item, "text");
  68. if (obj)
  69. {
  70. printf("text=%s\n", obj->valuestring);
  71. }
  72. obj = cJSON_GetObjectItem(item, "number");
  73. if (obj)
  74. {
  75. printf("number=%d\n", obj->valueint);
  76. }
  77. obj = cJSON_GetObjectItem(item, "state1");
  78. if (obj)
  79. {
  80. printf("state1=%d\n", obj->valueint);
  81. }
  82. obj = cJSON_GetObjectItem(item, "state2");
  83. if (obj)
  84. {
  85. printf("state2=%d\n", obj->valueint);
  86. }
  87. obj = cJSON_GetObjectItem(item, "state3");
  88. if (obj)
  89. {
  90. printf("state3=%d\n", obj->valueint);
  91. }
  92. }
  93. //3. 释放空间
  94. cJSON_Delete(root);
  95. return 0;
  96. }

 

 五、cJSON带数组的JSON数据

 目标: 使用cJSON创建出下面这样一个JSON格式数据


  
  1. {
  2. "text": [
  3. {
  4. "width": 1280,
  5. "height": 720
  6. },
  7. {
  8. "width": 1920,
  9. "height": 1080
  10. },
  11. {
  12. "width": 3840,
  13. "height": 2160
  14. }
  15. ]
  16. }

5.1 创建json数据


  
  1. #include <iostream>
  2. //因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
  3. extern "C" {
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "cJSON.h"
  7. }
  8. int main()
  9. {
  10. cJSON *width = NULL;
  11. cJSON *height = NULL;
  12. int i;
  13. const unsigned int resolution_numbers[3][2] = {
  14. {1280, 720},
  15. {1920, 1080},
  16. {3840, 2160}
  17. };
  18. //1. 创建cJSON对象
  19. cJSON* root = cJSON_CreateObject();
  20. //2. 创建数组对象
  21. cJSON *array = cJSON_CreateArray();
  22. cJSON_AddItemToObject(root, "text", array);
  23. for (i = 0; i < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++i)
  24. {
  25. cJSON *obj = cJSON_CreateObject();
  26. cJSON_AddItemToArray(array, obj);
  27. width = cJSON_CreateNumber(resolution_numbers[i][0]);
  28. cJSON_AddItemToObject(obj, "width", width);
  29. height = cJSON_CreateNumber(resolution_numbers[i][1]);
  30. cJSON_AddItemToObject(obj, "height", height);
  31. }
  32. //3. 打印生成的结果
  33. char *json_data=cJSON_PrintUnformatted(root);
  34. printf("%s\n",json_data);
  35. //4. 释放空间
  36. cJSON_Delete(root);
  37. return 0;
  38. }

5.2 解析JSON数据


  
  1. #include <iostream>
  2. //因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
  3. extern "C" {
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "cJSON.h"
  7. }
  8. //将要解析的JSON数据.
  9. char data[] =
  10. "{"
  11. "\"text\": ["
  12. "{"
  13. "\"width\": 1280,"
  14. "\"height\" : 720"
  15. "},"
  16. "{"
  17. "\"width\": 1920,"
  18. "\"height\" : 1080"
  19. "},"
  20. "{"
  21. "\"width\": 3840,"
  22. "\"height\" : 2160"
  23. "}"
  24. "]"
  25. "}";
  26. int main()
  27. {
  28. //1. 载入JSON数据
  29. cJSON* root = cJSON_Parse(data);
  30. if (root == NULL)return 0;
  31. //2. 解析字段
  32. cJSON* item;
  33. int i;
  34. item = cJSON_GetObjectItem(root, "text");
  35. if (item)
  36. {
  37. //获取数组的大小
  38. int ArraySize = cJSON_GetArraySize(item);
  39. //解析数组的里的每个成员
  40. for (i = 0; i < ArraySize; i++)
  41. {
  42. //取出数组下标对象
  43. cJSON *array_item = cJSON_GetArrayItem(item, i);
  44. if (array_item == NULL)continue;
  45. //解析数据
  46. cJSON *obj = cJSON_GetObjectItem(array_item, "width");
  47. if (obj)
  48. {
  49. printf("width=%d\n",obj->valueint);
  50. }
  51. obj = cJSON_GetObjectItem(array_item, "height");
  52. if (obj)
  53. {
  54. printf("height=%d\n", obj->valueint);
  55. }
  56. }
  57. }
  58. //3. 释放空间
  59. cJSON_Delete(root);
  60. return 0;
  61. }


 

文章来源: xiaolong.blog.csdn.net,作者:DS小龙哥,版权归原作者所有,如需转载,请联系作者。

原文链接:xiaolong.blog.csdn.net/article/details/120345217

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。