目录

  • 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. 问题记录

  1. date值是什么形式

  2. 打印输出后,换行符

  3. 小数点精度控制

    程序中调用如下:

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解析和打包相关推荐

  1. 全面详解c语言使用cJSON解析JSON字符

    为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件! 如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更 ...

  2. 用cJSON解析心知天气返回的数据包

    目录: 文章目录 调用天气API接口获取天气信息 解析天气信息字符串 测试结果 欢迎关注 后台网友留言,说参考这个链接 天气数据解析1–JSON格式数据 处理天气API接口返回的数据,中间遇到了点问题 ...

  3. 解决方法:STM32使用cJSON解析数据失败

    一.问题 在 STM32 移植 cJSON 库后,使用 cJSON_Parse(),解析失败. char cmd[512] = "{\"msg\":\"this ...

  4. 利用cJSON解析JSON格式

    目录 一.JSON格式 二.cJSON下载 三.cJSON常用函数接口 四.cJSON解析JSON案例 1.一层键值 2.多层键值(两次为例) 3.json数组解析 五.JSON添加数据 (与链表类似 ...

  5. openresty cjson解析json数据

    openresty cjson解析json数据 官网:https://github.com/mpx/lua-cjson 文档:https://kyne.com.au/~mark/software/lu ...

  6. cjson 对象是json数组型结构体_C语言 - cJSON解析特定格式 含有数组array类型的数据...

    在ESP32中使用了cJSON库,发现很好用.最近服务器端的JSON格式越来越多样,还是有些注意点,需要做下笔记记录下来. cJSON *MAC_arry = cJSON_GetObjectItem( ...

  7. cjson解析器说明

    1. cJSON cJson 是c语言编写的一个解析器. 是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器.主要两个文件cJSON.c 和cJSON.h . 主要用来编码 ...

  8. c语言遍历 json字符串,全面详解c语言使用cJSON解析JSON字符

    为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件! 如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更 ...

  9. c语言如何判断字符json,全面详解C语言使用cJSON解析JSON字符

    为什么选择cJSON来解析JSON字符串?因为简洁又简单,而且效率又快,cJSON工程文件也非常简单,仅一个.c文件和一个.h文件! 如果要自己写的话就是重造轮子了,况且效率上也不一定会比cJSON更 ...

最新文章

  1. R语言生存分析Log-rank假设检验组间生存曲线比较实战
  2. TensorFlow 变量共享,命名空间
  3. [IE编程] WebBrowser控件的多页面浏览(Tabbed Browsing)开发接口
  4. Django 笔记5 -- 数据库
  5. Android:获取最近打开app列表
  6. opengl光线追踪的程序_【PathTracing】实时光线追踪和BSSRDF的那些事
  7. 记录一次客户Oracle启动不了的解决过程
  8. (8)matplotlib 将点连成线
  9. java键盘钩子_java 写的低级鼠标键盘钩子示例
  10. E企云企业邮箱,选了不后悔
  11. Eclipse 绿豆沙
  12. Tracup:集成Bug追踪的轻量级项目管理平台
  13. STM32驱动U盘时KILE5中#error编译不通过
  14. 不重视需求过程的项目队伍将自食其果
  15. Android Things:外设I/O接口-GPIO
  16. 2005年商业科技盘点:最被低估10大技术+最被高估10大技术
  17. 宏定义 指针 c语言,C语言宏定义讲解(C和指针 笔记)
  18. java微信小程序音乐播放器分享系统
  19. 如何成为一名IT咨询顾问?
  20. Ubuntu16.04 装机之后要做的二十件事

热门文章

  1. Centos7 网络配置 设置静态Ip
  2. Android4火狐,Android版火狐4正式发布
  3. docker启动nginx代理不上_用 docker-compose 启动 nginx, network 为 host, nginx 无法启动是怎么回事?...
  4. concatenation java,Java:StringBufferConcatenation
  5. 汇编学习--7.10--程序编写
  6. python中reversed函数,Python3
  7. mysql innodb缓冲池_InnoDB 缓冲池
  8. fasterrcnn论文_论文笔记:Fast(er) RCNN
  9. 什么?都2021年了还不会ajax嘛,来这里让您快速学会Ajax
  10. C语言:求1到100之间的所有素数,并设定每行输出5个素数