c环境下Json字符串的解析
2015-09-08 18:09
537 查看
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();
主要代码如下:
对于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();
主要代码如下:
<pre name="code" class="html">#include <stdio.h> #include <string.h> #include "usifext.h" #include "json_parser.h" #include "cJSON.h" #include "gs_os.h" void parse_json_sub_type_others(cJSON** psub, json_node_info** tag_node, json_root_info** proot_node, json_node_info** tag_point, json_attr_info** tag_attr_node, int type) { int text_int = 0; char *text_string = ""; (*tag_node) = (json_node_info *)malloc(sizeof(json_node_info)); memset((*tag_node)->tag_name, 0, sizeof((*tag_node)->tag_name)); memset((*tag_node)->tag_text, 0, sizeof((*tag_node)->tag_text)); char *tag = (*psub)->string; if (cJSON_Number == type) { text_int = (*psub)->valueint; } else { text_string = (*psub)->valuestring; } if (strcmp(tag, JSON_HEADER_CONTROL_TAG) != 0) { strcpy((*tag_node)->tag_name, tag); if (cJSON_Number == type) { ITOA((*tag_node)->tag_text, text_int); } else { strcpy((*tag_node)->tag_text, text_string); } (*tag_node)->next = NULL; if ((*proot_node)->next == NULL) { (*proot_node)->next = (*tag_node); (*tag_point) = (*tag_node); } else { (*tag_point)->next = (*tag_node); (*tag_point) = (*tag_node); } } else { (*tag_attr_node) = (json_attr_info*)malloc(sizeof(json_attr_info)); memset((*tag_attr_node)->name, 0, sizeof((*tag_attr_node)->name)); memset((*tag_attr_node)->value, 0, sizeof((*tag_attr_node)->value)); strcpy((*tag_attr_node)->name, tag); if (cJSON_Number == type) { ITOA((*tag_attr_node)->value, text_int); } else { strcpy((*tag_attr_node)->value, text_string); } (*proot_node)->attr_list = (*tag_attr_node); } } void parse_json_sub_type_array(cJSON** psub, json_node_info** tag_node, json_root_info** proot_node, json_node_info** tag_point, json_attr_info** tag_attr_node) { int j = 0; for (j = 0; j < cJSON_GetArraySize((*psub)); j++) { cJSON *psub_sub = cJSON_GetArrayItem((*psub), j); if (psub_sub->type == cJSON_Object) { parse_json_sub_type_obj(&psub_sub, tag_node, proot_node, tag_point, tag_attr_node); } } } void parse_json_sub_type_obj(cJSON** psub, json_node_info** tag_node, json_root_info** proot_node, json_node_info** tag_point, json_attr_info** tag_attr_node) { int j = 0; for (j = 0; j < cJSON_GetArraySize((*psub)); j++) { cJSON *psub_sub = cJSON_GetArrayItem((*psub), j); parse_json_sub_type_others(&psub_sub, tag_node, proot_node, tag_point, tag_attr_node, psub_sub->type); } } int parse_cjson_to_json_root(cJSON *pjson, json_root_info *proot_node) { int i = 0; int size = 0; json_node_info* tag_node; json_attr_info* tag_attr_node; json_node_info* tag_point = NULL; if (NULL == proot_node) { return -1; } if (NULL == pjson) { return -1; } (proot_node)->next = NULL; size = cJSON_GetArraySize(pjson); for (i = 0; i < size; i++) { cJSON *psub = cJSON_GetArrayItem(pjson, i); switch (psub->type) { case cJSON_Array: parse_json_sub_type_array(&psub, &tag_node, &proot_node, &tag_point, &tag_attr_node); break; case cJSON_Object: parse_json_sub_type_obj(&psub, &tag_node, &proot_node, &tag_point, &tag_attr_node); break; case cJSON_String: case cJSON_Number: parse_json_sub_type_others(&psub, &tag_node, &proot_node, &tag_point, &tag_attr_node, psub->type); break; default: return -1; } } return 0; }其中涉及到一些自定义的函数, ITOA、GSOS_MALLOC().
int ITOA(char * str, unsigned long val) { char *p; char *first_dig; <span style="white-space:pre"> </span>char temp; unsigned t_val; int len = 0; p = str; first_dig = p; do { t_val = (unsigned)(val % 0x0a); val /= 0x0a; *p++ = (char)(t_val + '0'); len++; } while (val > 0); *p-- = '\0'; do { temp = *p; *p = *first_dig; *first_dig = temp; --p; ++first_dig; } while (first_dig < p); return len; }
</pre><pre name="code" class="html">采用递归的方式更加简单,主要函数和代码如下:
int parse_json(cJSON * pJson,xml_root_info *proot_node) { xml_node_info* tag_node; xml_attr_info* tag_attr_node; xml_node_info* tag_point = NULL; tag_node = (xml_node_info *) malloc(sizeof(xml_node_info)); memset(tag_node->tag_name,0,sizeof(tag_node->tag_name)); memset(tag_node->tag_text,0,sizeof(tag_node->tag_text)); tag_attr_node = (xml_attr_info*) malloc(sizeof(xml_attr_info)); memset(tag_attr_node->name,0,sizeof(tag_attr_node->name)); memset(tag_attr_node->value,0,sizeof(tag_attr_node->value)); tag_point = (xml_node_info *) malloc(sizeof(xml_node_info)); if(NULL == pJson) { return -1; } printf(" pJson->type :%d\n", pJson->type); switch(pJson->type) { case cJSON_False : { char *value_string = pJson->string; int value_int = pJson->valueint; strcpy(tag_node->tag_name, value_string); //ITOA(tag_attr_node->value, value_int); } break; case cJSON_True : { char *value_string = pJson->string; int value_int = pJson->valueint; strcpy(tag_node->tag_name, value_string); //ITOA(tag_attr_node->value, value_int); } break; case cJSON_NULL : { printf("%s : NULL\n", pJson->string); } break; case cJSON_Number : { char *value_string = pJson->string; int value_int = pJson->valueint; if(strcmp(value_string, "request") != 0) { strcpy(tag_node->tag_name, value_string); itoa(value_int, tag_node->tag_text, 10); tag_node->next = NULL; if(count == 0) { proot_node->next = tag_node; tag_point = tag_node; count++; } else { tag_point = (proot_node)->next; while(NULL != tag_point->next) { printf("up循环遍历里面\n"); tag_point = tag_point->next; printf("down循环遍历里面\n"); } tag_point->next = tag_node; tag_point = tag_node; } } else { strcpy(tag_attr_node->name, value_string); itoa(value_int, tag_attr_node->value, 10); proot_node->attr_list = tag_attr_node; //proot_node->next=NULL; } } break; case cJSON_String : { char *value_string = pJson->string; char *pJsonString = pJson->valuestring; if(strcmp(value_string, "request") != 0) { strcpy(tag_node->tag_name, value_string); strcpy(tag_node->tag_text, pJsonString); tag_node->next = NULL; if(count == 0) { proot_node->next = tag_node; tag_point = tag_node; count++; printf("count_01:%d\n", count); } else { tag_point = (proot_node)->next; while(NULL != tag_point->next) { printf("up循环遍历里面\n"); tag_point = tag_point->next; printf("down循环遍历里面\n"); } tag_point->next = tag_node; tag_point = tag_node; } } else { strcpy(tag_attr_node->name, value_string); strcpy(tag_attr_node->value, pJsonString); proot_node->attr_list = tag_attr_node; } } break; case cJSON_Array : case cJSON_Object : { int iSize = cJSON_GetArraySize(pJson); int i = 0; printf("%s\n", NULL == pJson->string ? "" : pJson->string); for(i = 0; i < iSize; i++) { cJSON * pSub = cJSON_GetArrayItem(pJson, i); parse_json(pSub, proot_node); } } break; default : return -1; break; } }
相关文章推荐
- 【jsp】input 控制输入类型
- js 倒计时
- js前台加密传输到后台C#解密
- javascript新手入门必读书籍推荐
- js整理3
- 只让页面刷新一次.用js来实现
- javascript 中的 delete
- js创建对象
- i18next-页面层语言国际化js框架介绍
- fastjson生成和解析json数据
- javascript中加法操作符与减法操作符在字符串与数字相加时的区别
- JavaScript总结(一)
- js中变量的作用域
- HtmlUnit解析document时js不能拿到body对象问题解决
- JS获取当前对象大小以及屏幕分辨率等
- 计算器的实现javaScripte
- 原生JS写toggleclass方法
- href="javascript:void(0)"
- 收集的很棒的JS,JQ代码
- js中的刷新页面