cJSON解析和打包
目录
- 1. JSON格式
- 2. 解析
- 3. 打包
- 4. 源码分析
- 5. 问题记录
1. JSON格式
JSON格式
C语言:json库的使用
cJSON库源代码获取:https://github.com/DaveGamble/cJSON.git
。
也可以从我的GitHub获取,包含了解析的打包的两个测试程序。
2. 解析
主要过程分为三步:
使用cJSON_Parse将字符串转换为cJSON结构。
使用cJSON_GetObjectItem获取指定键对应的值。
使用cJSON_Delete销毁创建的cJSON结构。
当涉及数组时,需要多使用两个函数:
int cJSON_GetArraySize(cJSON *array);
cJSON* cJSON_GetArrayItem(cJSON *array,int item);
使用cJSON解析JSON字符串
3. 打包
cJSON库的安装与使用
注意事项:主要是内存回收。
cJSON打包功能使用-代码案例、特别注意事项
4. 源码分析
cJSON源码分析
在test.c程序中,我们解析的是JSON如下:
char *Output2 = "{\"state\":1}";
对应到cJSON.c文件中的函数,重点看两个函数:
/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{if (!value) return 0; /* Fail on null. */if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }if (*value=='\"') { return parse_string(item,value); }if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }if (*value=='[') { return parse_array(item,value); }if (*value=='{') { return parse_object(item,value); }ep=value;return 0; /* failure. */
}
在此函数中,可以看到根据第一个字符进入不同分支。我们主要看parse_object
函数:
/* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{cJSON *child;if (*value!='{') {ep=value;return 0;} /* not an object! */item->type=cJSON_Object;value=skip(value+1);if (*value=='}') return value+1; /* empty array. */item->child=child=cJSON_New_Item();if (!item->child) return 0;value=skip(parse_string(child,skip(value)));if (!value) return 0;child->string=child->valuestring;child->valuestring=0;if (*value!=':') {ep=value;return 0;} /* fail! */value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */if (!value) return 0;while (*value==','){cJSON *new_item;if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */child->next=new_item;new_item->prev=child;child=new_item;value=skip(parse_string(child,skip(value+1)));if (!value) return 0;child->string=child->valuestring;child->valuestring=0;if (*value!=':') {ep=value;return 0;} /* fail! */value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */if (!value) return 0;}if (*value=='}') return value+1; /* end of array */ep=value;return 0; /* malformed. */
}
尤其要注意链表的指向。在此函数之前,先创建了一个空的cJSON结构体,作为起始节点。其child指向的结构体才开始存储信息:
valueint = 1
string = state
5. 问题记录
date值是什么形式
打印输出后,换行符
小数点精度控制
程序中调用如下:
value = cJSON_CreateNumber(120.8);
输出变为120.800000。查看sJSON.c文件,cJSON_CreateNumber函数定义如下:
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
在函数内部增加
printtf("%f",num)
发现num已经变为120.800000
如果把形参改为float,型,打印后为120.800003
未解决,保留。
临时解决办法为固定小数点后两位,需要修改sJSON.c文件中的print_number
函数
static char *print_number(cJSON *item,printbuffer *p)
{char *str=0;double d=item->valuedouble;if (d==0){if (p) str=ensure(p,2);else str=(char*)cJSON_malloc(2); /* special case for 0. */if (str) strcpy(str,"0");}else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN){if (p) str=ensure(p,21);else str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */if (str) sprintf(str,"%d",item->valueint);}else{if (p) str=ensure(p,64);else str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */if (str){if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);else sprintf(str,"%f",d);}}return str;
}
将最后一个sprintf修改为sprintf(str,"%.2lf",d);
cJSON解析和打包相关推荐
- 全面详解c语言使用cJSON解析JSON字符
为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件! 如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更 ...
- 用cJSON解析心知天气返回的数据包
目录: 文章目录 调用天气API接口获取天气信息 解析天气信息字符串 测试结果 欢迎关注 后台网友留言,说参考这个链接 天气数据解析1–JSON格式数据 处理天气API接口返回的数据,中间遇到了点问题 ...
- 解决方法:STM32使用cJSON解析数据失败
一.问题 在 STM32 移植 cJSON 库后,使用 cJSON_Parse(),解析失败. char cmd[512] = "{\"msg\":\"this ...
- 利用cJSON解析JSON格式
目录 一.JSON格式 二.cJSON下载 三.cJSON常用函数接口 四.cJSON解析JSON案例 1.一层键值 2.多层键值(两次为例) 3.json数组解析 五.JSON添加数据 (与链表类似 ...
- openresty cjson解析json数据
openresty cjson解析json数据 官网:https://github.com/mpx/lua-cjson 文档:https://kyne.com.au/~mark/software/lu ...
- cjson 对象是json数组型结构体_C语言 - cJSON解析特定格式 含有数组array类型的数据...
在ESP32中使用了cJSON库,发现很好用.最近服务器端的JSON格式越来越多样,还是有些注意点,需要做下笔记记录下来. cJSON *MAC_arry = cJSON_GetObjectItem( ...
- cjson解析器说明
1. cJSON cJson 是c语言编写的一个解析器. 是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器.主要两个文件cJSON.c 和cJSON.h . 主要用来编码 ...
- c语言遍历 json字符串,全面详解c语言使用cJSON解析JSON字符
为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件! 如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更 ...
- c语言如何判断字符json,全面详解C语言使用cJSON解析JSON字符
为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件! 如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更 ...
最新文章
- R语言生存分析Log-rank假设检验组间生存曲线比较实战
- TensorFlow 变量共享,命名空间
- [IE编程] WebBrowser控件的多页面浏览(Tabbed Browsing)开发接口
- Django 笔记5 -- 数据库
- Android:获取最近打开app列表
- opengl光线追踪的程序_【PathTracing】实时光线追踪和BSSRDF的那些事
- 记录一次客户Oracle启动不了的解决过程
- (8)matplotlib 将点连成线
- java键盘钩子_java 写的低级鼠标键盘钩子示例
- E企云企业邮箱,选了不后悔
- Eclipse 绿豆沙
- Tracup:集成Bug追踪的轻量级项目管理平台
- STM32驱动U盘时KILE5中#error编译不通过
- 不重视需求过程的项目队伍将自食其果
- Android Things:外设I/O接口-GPIO
- 2005年商业科技盘点:最被低估10大技术+最被高估10大技术
- 宏定义 指针 c语言,C语言宏定义讲解(C和指针 笔记)
- java微信小程序音乐播放器分享系统
- 如何成为一名IT咨询顾问?
- Ubuntu16.04 装机之后要做的二十件事
热门文章
- Centos7 网络配置 设置静态Ip
- Android4火狐,Android版火狐4正式发布
- docker启动nginx代理不上_用 docker-compose 启动 nginx, network 为 host, nginx 无法启动是怎么回事?...
- concatenation java,Java:StringBufferConcatenation
- 汇编学习--7.10--程序编写
- python中reversed函数,Python3
- mysql innodb缓冲池_InnoDB 缓冲池
- fasterrcnn论文_论文笔记:Fast(er) RCNN
- 什么?都2021年了还不会ajax嘛,来这里让您快速学会Ajax
- C语言:求1到100之间的所有素数,并设定每行输出5个素数