当前位置:   article > 正文

c环境下Json字符串的解析_cjson 解析 long

cjson 解析 long

c环境下Json字符串的解析

对于Json字符串,最常见的方式就是一个一个的键值对被一个大的Obect包裹着,但是往往由于实际项目需要json字符串不可能保持最简单的形式来进行数据传输。

以最近一个小项目为例:

从手机客户端组织数据,形成Json字符串的主要形式有如下几种:

1. char *xjson = "[{\"TotalNum\":123},{\"Tvstate\":2},{\"ProgrameId\":014000789},{\"request\":1004}]";

2.char *xjson = "{\"TotalNum\":\"123\",\"name\":\"mao\",\"request\":1004}";

3.char *xjson = "{\"ToIndex\":\"99\",\"FromIndex\":\"0\",\"request\":\"0\"}";

4.char *xjson = "{\"array\":[{\"TotalNum\": 123,\"Tvstate\": \"2\"}],\"request\": 44}";

5.char *xjson = "{\"array\":[{\"TotalNum\": 123},{\"Tvstate\": \"2\"}],\"request\": \"44\"}";

6.char *xjson = "{\"TvSate\":0,\"FavMark\":64,\"FavGroupId\":\"\",\"array\":[{\"ProgrameId\": \"4334\"},{\"ProgrameId\":4334}],\"TotalNum\":3,\"request\":1004}";

7.char *xjson =  "{\"array\":[{\"data\":\"M040\"},{\"uuid\":\"860806027379485-38:BC:1A:87:E0:26\"}],\"request\":\"998\"}";

8.char *xjson = "{\"request\":1004}";

需要在机顶盒端接收到手机客户端发送过来的json字符串数据,并且将其解析出来存放到各自对应的已经实现定义好的结构体中。

大致的过程就是:

APK -------发送Json字符串给------>服务器端------解析json字符串到------>C结构体

那么具体的需求就是:

在服务器端的解析函数必须能够适配解析不同的json字符串。在不知道每一个json字符串的键值对的情况下,取出该json字符串的键值,存放在c结构体中,并且将这些结构体以链表的形式存放在内存中。

在c语言环境下有一个开源的cJSON库,其中封装好了一些列对json数据进行操作的函数。

cJSON结构体定义如下:

typedefstruct cJSON {

structcJSON *next,*prev;

struct cJSON *child;

int type;

char * valuestring;

int valueint;

double valuedouble;

char *string;

}cJSON;

其中type取值共有7中,分别是:

#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

考虑到我们在客户端组织起来的json字符串主要由Number、String、Array、Object组成,因此采用多重嵌套swicth进行解析。当然也可以使用递归进行解析,但是由于递归在项目开发中特别是嵌入式开发中一般不建议使用,所以这次并没有采用递归的方法进行解析。

具体的解析代码

其中涉及到的主要函数为:

解析的入口函数:parse_cjson_to_json_root()

解析子json结构体为Array的函数:parse_json_sub_type_array();

解析子json结构体为Object的函数:parse_json_sub_type_object();

解析子json结构体为Number和String的函数:parse_json_sub_type_others();


主要代码如下:

  1. <pre name="code" class="html">#include <stdio.h>
  2. #include <string.h>
  3. #include "usifext.h"
  4. #include "json_parser.h"
  5. #include "cJSON.h"
  6. #include "gs_os.h"
  7. void parse_json_sub_type_others(cJSON** psub, json_node_info** tag_node, json_root_info** proot_node, json_node_info** tag_point,
  8. json_attr_info** tag_attr_node, int type)
  9. {
  10. int text_int = 0;
  11. char *text_string = "";
  12. (*tag_node) = (json_node_info *)malloc(sizeof(json_node_info));
  13. memset((*tag_node)->tag_name, 0, sizeof((*tag_node)->tag_name));
  14. memset((*tag_node)->tag_text, 0, sizeof((*tag_node)->tag_text));
  15. char *tag = (*psub)->string;
  16. if (cJSON_Number == type)
  17. {
  18. text_int = (*psub)->valueint;
  19. }
  20. else
  21. {
  22. text_string = (*psub)->valuestring;
  23. }
  24. if (strcmp(tag, JSON_HEADER_CONTROL_TAG) != 0)
  25. {
  26. strcpy((*tag_node)->tag_name, tag);
  27. if (cJSON_Number == type)
  28. {
  29. ITOA((*tag_node)->tag_text, text_int);
  30. }
  31. else
  32. {
  33. strcpy((*tag_node)->tag_text, text_string);
  34. }
  35. (*tag_node)->next = NULL;
  36. if ((*proot_node)->next == NULL)
  37. {
  38. (*proot_node)->next = (*tag_node);
  39. (*tag_point) = (*tag_node);
  40. }
  41. else
  42. {
  43. (*tag_point)->next = (*tag_node);
  44. (*tag_point) = (*tag_node);
  45. }
  46. }
  47. else
  48. {
  49. (*tag_attr_node) = (json_attr_info*)malloc(sizeof(json_attr_info));
  50. memset((*tag_attr_node)->name, 0, sizeof((*tag_attr_node)->name));
  51. memset((*tag_attr_node)->value, 0, sizeof((*tag_attr_node)->value));
  52. strcpy((*tag_attr_node)->name, tag);
  53. if (cJSON_Number == type)
  54. {
  55. ITOA((*tag_attr_node)->value, text_int);
  56. }
  57. else
  58. {
  59. strcpy((*tag_attr_node)->value, text_string);
  60. }
  61. (*proot_node)->attr_list = (*tag_attr_node);
  62. }
  63. }
  64. void parse_json_sub_type_array(cJSON** psub, json_node_info** tag_node, json_root_info** proot_node, json_node_info** tag_point,
  65. json_attr_info** tag_attr_node)
  66. {
  67. int j = 0;
  68. for (j = 0; j < cJSON_GetArraySize((*psub)); j++)
  69. {
  70. cJSON *psub_sub = cJSON_GetArrayItem((*psub), j);
  71. if (psub_sub->type == cJSON_Object)
  72. {
  73. parse_json_sub_type_obj(&psub_sub, tag_node, proot_node, tag_point, tag_attr_node);
  74. }
  75. }
  76. }
  77. void parse_json_sub_type_obj(cJSON** psub, json_node_info** tag_node, json_root_info** proot_node, json_node_info** tag_point,
  78. json_attr_info** tag_attr_node)
  79. {
  80. int j = 0;
  81. for (j = 0; j < cJSON_GetArraySize((*psub)); j++)
  82. {
  83. cJSON *psub_sub = cJSON_GetArrayItem((*psub), j);
  84. parse_json_sub_type_others(&psub_sub, tag_node, proot_node, tag_point, tag_attr_node, psub_sub->type);
  85. }
  86. }
  87. int parse_cjson_to_json_root(cJSON *pjson, json_root_info *proot_node)
  88. {
  89. int i = 0;
  90. int size = 0;
  91. json_node_info* tag_node;
  92. json_attr_info* tag_attr_node;
  93. json_node_info* tag_point = NULL;
  94. if (NULL == proot_node)
  95. {
  96. return -1;
  97. }
  98. if (NULL == pjson)
  99. {
  100. return -1;
  101. }
  102. (proot_node)->next = NULL;
  103. size = cJSON_GetArraySize(pjson);
  104. for (i = 0; i < size; i++)
  105. {
  106. cJSON *psub = cJSON_GetArrayItem(pjson, i);
  107. switch (psub->type)
  108. {
  109. case cJSON_Array:
  110. parse_json_sub_type_array(&psub, &tag_node, &proot_node, &tag_point, &tag_attr_node);
  111. break;
  112. case cJSON_Object:
  113. parse_json_sub_type_obj(&psub, &tag_node, &proot_node, &tag_point, &tag_attr_node);
  114. break;
  115. case cJSON_String:
  116. case cJSON_Number:
  117. parse_json_sub_type_others(&psub, &tag_node, &proot_node, &tag_point, &tag_attr_node, psub->type);
  118. break;
  119. default:
  120. return -1;
  121. }
  122. }
  123. return 0;
  124. }
其中涉及到一些自定义的函数, ITOA、GSOS_MALLOC().

 
  1. int ITOA(char * str, unsigned long val)
  2. {
  3. char *p;
  4. char *first_dig;
  5. <span style="white-space:pre"> </span>char temp;
  6. unsigned t_val;
  7. int len = 0;
  8. p = str;
  9. first_dig = p;
  10. do
  11. {
  12. t_val = (unsigned)(val % 0x0a);
  13. val   /= 0x0a;
  14. *p++ = (char)(t_val + '0');
  15. len++;
  16. }
  17. while (val > 0);
  18. *p-- = '\0';
  19. do
  20. {
  21. temp = *p;
  22. *p   = *first_dig;
  23. *first_dig = temp;
  24. --p;
  25. ++first_dig;
  26. }
  27. while (first_dig < p);
  28. return len;
  29. }
</pre><pre name="code" class="html">采用递归的方式更加简单,主要函数和代码如下:
  1. int parse_json(cJSON * pJson,xml_root_info *proot_node)
  2. {
  3.     xml_node_info* tag_node;
  4. xml_attr_info* tag_attr_node;
  5. xml_node_info* tag_point = NULL;
  6.     tag_node = (xml_node_info *) malloc(sizeof(xml_node_info));
  7.     memset(tag_node->tag_name,0,sizeof(tag_node->tag_name));
  8.     memset(tag_node->tag_text,0,sizeof(tag_node->tag_text));
  9.     tag_attr_node = (xml_attr_info*) malloc(sizeof(xml_attr_info));
  10.     memset(tag_attr_node->name,0,sizeof(tag_attr_node->name));
  11.     memset(tag_attr_node->value,0,sizeof(tag_attr_node->value));
  12.     tag_point = (xml_node_info *) malloc(sizeof(xml_node_info));
  13.     if(NULL == pJson)
  14.     {
  15.         return -1;
  16.     }
  17.     printf(" pJson->type :%d\n", pJson->type);
  18.     switch(pJson->type)
  19.     {
  20.         case cJSON_False :
  21.             {
  22.                 char *value_string = pJson->string;
  23.                 int value_int = pJson->valueint;
  24.                 strcpy(tag_node->tag_name, value_string);
  25.                 //ITOA(tag_attr_node->value, value_int);
  26.             }
  27.             break;
  28.         case cJSON_True :
  29.             {
  30.                 char *value_string = pJson->string;
  31.                 int value_int = pJson->valueint;
  32.                 strcpy(tag_node->tag_name, value_string);
  33.                 //ITOA(tag_attr_node->value, value_int);
  34.             }
  35.             break;
  36.         case cJSON_NULL :
  37.             {
  38.                 printf("%s : NULL\n", pJson->string);
  39.             }
  40.             break;
  41.         case cJSON_Number :
  42.             {
  43.                 char *value_string = pJson->string;
  44.                 int value_int = pJson->valueint;
  45.                 if(strcmp(value_string, "request") != 0)
  46.                 {
  47. strcpy(tag_node->tag_name, value_string);
  48. itoa(value_int, tag_node->tag_text, 10);
  49. tag_node->next = NULL;
  50. if(count == 0)
  51. {
  52. proot_node->next = tag_node;
  53. tag_point = tag_node;
  54. count++;
  55. }
  56. else
  57. {
  58. tag_point = (proot_node)->next;
  59. while(NULL != tag_point->next)
  60. {
  61. printf("up循环遍历里面\n");
  62. tag_point = tag_point->next;
  63. printf("down循环遍历里面\n");
  64. }
  65. tag_point->next = tag_node;
  66. tag_point = tag_node;
  67. }
  68.                 }
  69.                 else
  70.                 {
  71. strcpy(tag_attr_node->name, value_string);
  72. itoa(value_int, tag_attr_node->value, 10);
  73. proot_node->attr_list = tag_attr_node;
  74. //proot_node->next=NULL;
  75.                 }
  76.             }
  77.             break;
  78.         case cJSON_String :
  79.             {
  80.                 char *value_string = pJson->string;
  81.                 char *pJsonString = pJson->valuestring;
  82.                 if(strcmp(value_string, "request") != 0)
  83.                 {
  84. strcpy(tag_node->tag_name, value_string);
  85. strcpy(tag_node->tag_text, pJsonString);
  86. tag_node->next = NULL;
  87. if(count == 0)
  88. {
  89. proot_node->next = tag_node;
  90. tag_point = tag_node;
  91. count++;
  92. printf("count_01:%d\n", count);
  93. }
  94. else
  95. {
  96. tag_point = (proot_node)->next;
  97. while(NULL != tag_point->next)
  98. {
  99. printf("up循环遍历里面\n");
  100. tag_point = tag_point->next;
  101. printf("down循环遍历里面\n");
  102. }
  103. tag_point->next = tag_node;
  104. tag_point = tag_node;
  105. }
  106.                 }
  107.                 else
  108.                 {
  109. strcpy(tag_attr_node->name, value_string);
  110. strcpy(tag_attr_node->value, pJsonString);
  111. proot_node->attr_list = tag_attr_node;
  112.                 }
  113.             }
  114.             break;
  115.         case cJSON_Array  :
  116.         case cJSON_Object :
  117.             {
  118.                 int iSize = cJSON_GetArraySize(pJson);
  119.                 int i = 0;
  120.                 printf("%s\n", NULL == pJson->string ? "" : pJson->string);
  121.                 for(i = 0; i < iSize; i++)
  122.                 {
  123.                     cJSON * pSub = cJSON_GetArrayItem(pJson, i);
  124.                     parse_json(pSub, proot_node);
  125.                 }
  126.             }
  127.             break;
  128.         default :
  129.             return -1;
  130.             break;
  131.     }
  132. }


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