当前位置:   article > 正文

cJSON介绍及使用

cjson

JSON(JavaScript Object Notation)是一种轻量级的文本数据交换格式,易于让人阅读。同时也易于机器解析和生成。尽管JSON是Javascript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯。JSON解析器和JSON库支持许多不同的编程语言。

几乎所有与网页开发相关的语言都有JSON库。JSON比XML更小、更快。

JSON用于描述数据结构,有以下形式存在:

(1)、对象(object):一个对象以”{“开始,并以”}”结束。一个对象包含一系列非排序的名称/值对,每个名称/值对之间使用”,”分隔。

(2)、名称/值(collection):名称和值之间使用”:”隔开。一个名称是一个字符串;一个值 (value)可以是双引号括起来的字符串(string)、数值(number)、true、false、null、对象(object)或者数组(array)。这些结构可以嵌套。

JSON语法规则:(1)、数据在键值对中;(2)、数据由逗号分隔;(3)、花括号保存对象;(4)、方括号保存数组。

JSON的值可以是:

(1)、数值:一系列0--9的数字组合,可以为负数或者小数。还可以用”e”或者”E”表示为指数形式。数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

(2)、字符串:以""括起来的一串字符。字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。字符串(string)与C或者Java的字符串非常相似。

(3)、布尔值:表示为true或者false。

(4)、数组(Array):数组是值(value)的有序集合。一个数组以”[“(左中括号)开始,”]”(右中括号)结束。值之间使用”,”(逗号)分隔。数组索引从0开始。

(5)、对象(object):对象是一个无序的”名称/值”对集合。一个对象以”{“开始,并以”}”结束。每个”名称”后跟一个”:”(冒号)。”名称/值”对之间使用”,”(逗号)分隔。

(6)、null:空白可以加入到任何符号之间。

各式各样开源的JSON库非常多,这里介绍下GitHub上DaveGamble的cJSON库的使用,地址: https://github.com/DaveGamble/cJSON  ,它用起来非常方便。

关于json11的使用可以参考:https://blog.csdn.net/fengbingchun/article/details/51396932

cJSON是一个仅有一个.h文件,一个.c文件组成的JSON解析器,它是由纯C(ANSI C89)实现的,跨平台性较好。cJSON中有一个cJSON结构体。cJSON是采用链表存储的。

以下是测试代码:

  1. #include "funset.hpp"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "cJSON.h"
  6. #ifdef _MSC_VER
  7. #include <Windows.h>
  8. void utf8_to_gbk(const char* utf8, char* gbk)
  9. {
  10. const int maxlen = 256;
  11. wchar_t unicode_str[maxlen];
  12. int outlen = MultiByteToWideChar(CP_UTF8, 0, utf8, strlen(utf8), unicode_str, maxlen);
  13. outlen = WideCharToMultiByte(CP_ACP, 0, unicode_str, outlen, gbk, 256, NULL, NULL);
  14. gbk[outlen] = '\0';
  15. }
  16. #else // linux
  17. void utf8_to_gbk(const char* utf8, char* gbk)
  18. {
  19. strcpy(gbk, utf8);
  20. }
  21. #endif
  22. int read_file(const char* filename, char** content)
  23. {
  24. // open in read binary mode
  25. FILE* file = fopen(filename, "rb");
  26. if (file == NULL) {
  27. fprintf(stderr, "read file fail: %s\n", filename);
  28. return -1;
  29. }
  30. // get the length
  31. fseek(file, 0, SEEK_END);
  32. long length = ftell(file);
  33. fseek(file, 0, SEEK_SET);
  34. // allocate content buffer
  35. *content = (char*)malloc((size_t)length + sizeof(""));
  36. // read the file into memory
  37. size_t read_chars = fread(*content, sizeof(char), (size_t)length, file);
  38. if ((long)read_chars != length) {
  39. fprintf(stderr, "length dismatch: %d, %d\n", read_chars, length);
  40. free(*content);
  41. return -1;
  42. }
  43. (*content)[read_chars] = '\0';
  44. fclose(file);
  45. return 0;
  46. }
  47. int test_cjson_1()
  48. {
  49. #ifdef __linux__
  50. const char* filename = "testdata/cjson_test7";
  51. #else
  52. const char* filename = "E:/GitCode/Messy_Test/testdata/cjson_test7";
  53. #endif
  54. char *json = NULL;
  55. if (read_file(filename, &json) != 0) return -1;;
  56. if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0')) {
  57. fprintf(stderr, "file content is null\n");
  58. return -1;
  59. }
  60. cJSON* item = cJSON_Parse(json + 2);
  61. if (item == NULL) {
  62. fprintf(stderr, "pasre json file fail\n");
  63. return -1;
  64. }
  65. int do_format = 0;
  66. if (json[1] == 'f') do_format = 1;
  67. char *printed_json = NULL;
  68. if (json[0] == 'b') {
  69. // buffered printing
  70. printed_json = cJSON_PrintBuffered(item, 1, do_format);
  71. } else {
  72. // unbuffered printing
  73. if (do_format) printed_json = cJSON_Print(item);
  74. else printed_json = cJSON_PrintUnformatted(item);
  75. }
  76. if (printed_json == NULL) {
  77. fprintf(stderr, "print json fail\n");
  78. return -1;
  79. }
  80. printf("%s\n", printed_json);
  81. int num = cJSON_GetArraySize(item);
  82. for (int i = 0; i < num; ++i) {
  83. cJSON* arr = cJSON_GetArrayItem(item, i);
  84. if (arr == NULL) {
  85. fprintf(stderr, "get array item fail\n");
  86. return -1;
  87. }
  88. fprintf(stdout, "has item \"City\": %d; has item \"abc\": %d\n",
  89. cJSON_HasObjectItem(arr, "City"), cJSON_HasObjectItem(arr, "abc"));
  90. cJSON* tmp = cJSON_GetObjectItem(arr, "City");
  91. if (tmp != NULL)
  92. fprintf(stdout, "key: %s, value: %s\n", tmp->string, tmp->valuestring);
  93. }
  94. if (item != NULL) cJSON_Delete(item);
  95. if (json != NULL) free(json);
  96. if (printed_json != NULL) free(printed_json);
  97. return 0;
  98. }
  99. int test_cjson_2()
  100. {
  101. #ifdef __linux__
  102. const char* filename = "testdata/json.data";
  103. #else
  104. const char* filename = "E:/GitCode/Messy_Test/testdata/json.data";
  105. #endif
  106. char *json = NULL;
  107. if (read_file(filename, &json) != 0) return -1;;
  108. if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0')) {
  109. fprintf(stderr, "file content is null\n");
  110. return -1;
  111. }
  112. cJSON* items = cJSON_Parse(json);
  113. if (items == NULL) {
  114. fprintf(stderr, "pasre json file fail\n");
  115. return -1;
  116. }
  117. char* printed_json = cJSON_PrintUnformatted(items);
  118. if (printed_json == NULL) {
  119. fprintf(stderr, "print json fail\n");
  120. return -1;
  121. }
  122. printf("%s\n\n", printed_json);
  123. cJSON* item = cJSON_GetObjectItem(items, "name");
  124. fprintf(stdout, "key: %s, value: %s\n", "name", item->valuestring);
  125. char gbk[256];
  126. item = cJSON_GetObjectItem(items, "address");
  127. utf8_to_gbk(item->valuestring, gbk);
  128. fprintf(stdout, "key: %s, value: %s\n", "address", gbk);
  129. item = cJSON_GetObjectItem(items, "age");
  130. fprintf(stdout, "key: %s, value: %d\n", "age", item->valueint);
  131. item = cJSON_GetObjectItem(items, "value1");
  132. int size = cJSON_GetArraySize(item);
  133. for (int i = 0; i < size; ++i) {
  134. cJSON* tmp = cJSON_GetArrayItem(item, i);
  135. int len = cJSON_GetArraySize(tmp);
  136. fprintf(stdout, "key: %s:", "value1");
  137. for (int j = 0; j < len; ++j) {
  138. cJSON* tmp2 = cJSON_GetArrayItem(tmp, j);
  139. fprintf(stdout, " %f,", tmp2->valuedouble);
  140. }
  141. fprintf(stdout, "\n");
  142. }
  143. item = cJSON_GetObjectItem(items, "value2");
  144. size = cJSON_GetArraySize(item);
  145. fprintf(stdout, "key: %s:", "value2");
  146. for (int i = 0; i < size; ++i) {
  147. cJSON* tmp = cJSON_GetArrayItem(item, i);
  148. fprintf(stdout, " %f,", tmp->valuedouble);
  149. }
  150. fprintf(stdout, "\n");
  151. item = cJSON_GetObjectItem(items, "bei_jing");
  152. cJSON* tmp = cJSON_GetObjectItem(item, "address");
  153. utf8_to_gbk(tmp->valuestring, gbk);
  154. fprintf(stdout, "key: %s, value: %s\n", "address", gbk);
  155. tmp = cJSON_GetObjectItem(item, "car");
  156. fprintf(stdout, "key: %s, value: %d\n", "car", tmp->valueint);
  157. tmp = cJSON_GetObjectItem(item, "cat");
  158. fprintf(stdout, "key: %s, value: %d\n", "cat", tmp->valueint);
  159. item = cJSON_GetObjectItem(items, "shan_dong");
  160. tmp = cJSON_GetObjectItem(item, "address");
  161. utf8_to_gbk(tmp->valuestring, gbk);
  162. fprintf(stdout, "key: %s, value: %s\n", "address", gbk);
  163. tmp = cJSON_GetObjectItem(item, "value1");
  164. size = cJSON_GetArraySize(tmp);
  165. for (int i = 0; i < size; ++i) {
  166. char* names[2] = { "ji_nan", "tai_an" };
  167. cJSON* tmp2 = cJSON_GetArrayItem(tmp, i);
  168. cJSON* tmp3 = cJSON_GetObjectItem(tmp2, names[i]);
  169. utf8_to_gbk(tmp3->valuestring, gbk);
  170. fprintf(stdout, "key: %s, value: %s\n",names[i], gbk);
  171. }
  172. if (items != NULL) cJSON_Delete(items);
  173. if (json != NULL) free(json);
  174. if (printed_json != NULL) free(printed_json);
  175. return 0;
  176. }

其中test_cjson_2()函数是解析如下json的测试代码:

  1. {
  2. "name": "spring",
  3. "address": "北京",
  4. "age": 30,
  5. "value1": [[23, 43, -2.3, 6.7, 90],
  6. [-9, -19, 10, 2],
  7. [-5, -55]],
  8. "value2": [13.3, 1.9, 2.10],
  9. "bei_jing": {
  10. "address": "海淀",
  11. "car": false,
  12. "cat": true
  13. },
  14. "shan_dong": {
  15. "address": "济南",
  16. "value1": [{"ji_nan": "趵突泉"}, {"tai_an": "泰山"}]
  17. }
  18. }

程序执行结果如下:

GitHubhttps://github.com/fengbingchun/Messy_Test  

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/427562
推荐阅读
相关标签
  

闽ICP备14008679号