一. 简介

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

其中,定义了一个cJSON的数据结构,用来储存数据.是以链表的形式.结构体如下:

在.h文件下

typedef struct cJSON {
struct cJSON *next,*prev; //双向链表
struct cJSON *child; //指向字节点,主要是在数组结构中用
int type; //类型,有7种类型,也就是说可以储存7种形式数据
/*分别为:
1. cJSON_False
2. cJSON_True
3. cJSON_NULL
4. cJSON_Number
5. cJSON_String
6. cJSON_Array
7. cJSON_Object */
char *valuestring; // 如果类型为cJSON_String 时用来存那个字符串
int valueint; //如果类型为cJSON_Number 时用来存值 ,这个主要存int型,如果是小数会有类型转换
double valuedouble; //这个存浮点数,如果是整数也会转换为浮点型,和valueint一起存同一个数据
char *string; //用来存字节点名字.主要是object时用.
} cJSON;

二. 把数据组织成结构(也就是节点组成结构)

下面的函数来产生各种类型的节点.

1 extern cJSON *cJSON_CreatNULL(void);
2 extern cJSON *cJSON_CreateTrue(void);
3 extern cJSON *cJSON_CreateFalse(void);
4 extern cJSON *cJSON_CreateBool(int b);
5 extern cJSON *cJSON_CreateNumber(double num);
6 extern cJSON *cJSON_CreateString(const char *string);
7 extern cJSON *cJSON_CreateArray(void);
8 extern cJSON *cJSON_CreateObject(void);

这些函数主要是把类型type写入节点,并且把相关的值也写入节点.比如创造字符串节点函数,还要把字符串指针valuestring指向相应字符串.

下面的函数创造数组节点集.也就是先创建一个数组类型的节点(用cJSON_CreateArray(void)函数 ),再把number数组的数据分别放在一个结点中(比如一个个int型数据的节点),并链表串起来(用suffix_object()函数).最后都悬挂在数组节点的字节点上(也就是结构体中的child指针指向它们),最后的最后返回数组的指针.

1 extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
2 extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
3 extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
4 extern cJSON *cJSON_CreateStringArray(const char **strings,int count); 

下面图例一个说明创建一个数型数组的过程:

三. 打包结构数据

组织好数据后就要已一定的格式把结构组织成字符串,便于传递. 使用函数:

1 extern char *cJSON_Print(cJSON *item);

2 extern char *cJSON_PrintUnformatted(cJSON *item);

说明:

如例子:

1 out=cJSON_Print(root); //就把结构root以一定的方式打包成字符串out.

分析一下打印的方式:

两种打印方式: 有格式和无格式两种;

cJSON_Print(root); 内部调用print_value(item,0, 1),而cJSON_PrintUnformatted(cJSON *item);内部调用print_value(item,0,0),

而print_value()函数里面分情况解析如下:

 1 switch ((item->type)&255)
2 {
3 case cJSON_NULL: out=cJSON_strdup("null"); break;
4 case cJSON_False: out=cJSON_strdup("false");break;
5 case cJSON_True: out=cJSON_strdup("true"); break;
6 case cJSON_Number: out=print_number(item);break;
7 case cJSON_String: out=print_string(item);break;
8 case cJSON_Array: out=print_array(item,depth,fmt);break;
9 case cJSON_Object: out=print_object(item,depth,fmt);break;
10 }

所以对于数值, 字符串, 数组和object来说 ,又有各自的函数print_number和print_string 函数就是以一定方式储存成字符串.而 print_array 和 print_object 函数又是对上两个函数的封装.

一般再调用函数删除前面的结构:

1 extern void cJSON_Delete(cJSON *c);

如例子:

1 cJSON_Delete(root);

这样就把数据彻底打包完成,可以传递或储存了.

四. 解析,还原结构

其中有几个辅助函数,先介绍一下:

1 //得到数组的长度,也就是子节点的个数.
2 extern int cJSON_GetArraySize(cJSON *array);
3 //得到数组的第item个节点.
4 extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
5 //得到名为string的节点.
6 extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);

解析采用分层解析的形式,一步一步解到最后一层.

和打印的方式一样,打印是:如果是数组或object , 则继续向下打印. 直到到子节点, 数值或字符串或其他,然后打印.. 解析应该正好相反. 比如最上层是数组, 那么先解析数组,然后得出数组大小, 再得出每一个数组节点, 如果不是最终节点. 还要往下: 先打印这个子节点,再解析,再得出子节点的子节点, 最后打印出来.就是节点的值了.

例子如下:

 1 cJSON * root,*arrayItem,*item,*name,*path,*flag;
2 int i = 0,size = 0;
3 char *pr = NULL,*na = NULL,*pa = NULL,*fl = NULL;
4 //将字符串解析成json结构体
5 root = cJSON_Parse(out);
6 //根据结构体获取数组大小
7 size = cJSON_GetArraySize(root);
8 //printf("%d\n",size);
9 //遍历数组
10 for(i=0;i < size; i++)
11 {
12 //获取第i个数组项
13 arrayItem = cJSON_GetArrayItem(root,i);
14 if(arrayItem)
15 {
16 //printf("%s\n","start......");
17 //讲json结构体转换成字符串
18 pr = cJSON_Print(arrayItem);
19 item = cJSON_Parse(pr);
20 name = cJSON_GetObjectItem(item,"name");
21 path = cJSON_GetObjectItem(item,"path");
22 flag = cJSON_GetObjectItem(item,"flag");
23 na = cJSON_Print(name);
24 pa = cJSON_Print(path);
25 fl = cJSON_Print(flag);
26 //printf("%s\n",pr);
27 printf("name:%s\n",na);
28 printf("path:%s\n",pa);
29 printf("flag:%s\n\n",fl);
30 }
31 }

————————————————
版权声明:本文为CSDN博主「xz_free」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ldk_0819/article/details/62215507

cJSON解析器总结[转载]的更多相关文章

  1. [转载]开发 Spring 自定义视图和视图解析器

    原文出处 http://www.ibm.com/developerworks/cn/java/j-lo-springview/ 概述 Spring 3.0 默认包含了多种视图和视图解析器,比如 JSP ...

  2. Spring MVC-视图解析器(View Resolverr)-多重解析器(Multiple Resolver)示例(转载实践)

    以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_multiple_resolver_mapping.htm 说明:示例基于Spri ...

  3. Spring MVC-控制器(Controller)-参数方法名称解析器(Parameter Method Name Resolver )示例(转载实践)

    以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_parametermethodnameresolver.htm 说明:示例基于Sp ...

  4. 转载:Jsoup常用方法功能介绍(html解析器)

    jsoup 的作用:是一款 Java 的HTML 解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操作数据 ...

  5. vert.x学习(四),使用模板解析器ClassLoaderTemplateResolver

    在vert.x中使用模板解析,可以为我们带来很多方便.我这里学习了一下ClassLoaderTemplateResolver的简单使用.这次工程配置与上篇一样,不需要做任何多的配置.直接编写代码就可以 ...

  6. Atiit 如何手写词法解析器

    Atiit 如何手写词法解析器 1.1. 通过编程直接从正则->nfa->dfa->表驱动词法解析一条龙自动生成.那是用程序自动生成是需要这样的,自己手写完全不必要这么复杂1 1.2 ...

  7. 自己动手写中文分词解析器完整教程,并对出现的问题进行探讨和解决(附完整c#代码和相关dll文件、txt文件下载)

    中文分词插件很多,当然都有各自的优缺点,近日刚接触自然语言处理这方面的,初步体验中文分词. 首先感谢harry.guo楼主提供的学习资源,博文链接http://www.cnblogs.com/harr ...

  8. atitit.java解析sql语言解析器解释器的实现

    atitit.java解析sql语言解析器解释器的实现 1. 解析sql的本质:实现一个4gl dsl编程语言的编译器 1 2. 解析sql的主要的流程,词法分析,而后进行语法分析,语义分析,构建sq ...

  9. 转:TinyXM--优秀的C++ XML解析器

    读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好. TinyXML是一个开源的解 ...

  10. python模块介绍- HTMLParser 简单的HTML和XHTML解析器

    python模块介绍- HTMLParser 简单的HTML和XHTML解析器 2013-09-11 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq ...

随机推荐

  1. OpenTelemetry 101:面向 IT 领导者和爱好者的非技术指南

    如果您从事软件开发. SRE或DevOps工作,您可能听说过可观察性.遥测和跟踪等术语.这些概念对于理解应用程序在生产环境中的行为至关重要,并且它们是现代软件开发实践的重要组成部分. 您可能还听说过在 ...

  2. SQL SERVER日常运维巡检系列——数据库备份

    前言 做好日常巡检是数据库管理和维护的重要步骤,而且需要对每次巡检日期.结果进行登记,同时可能需要出一份巡检报告. 本系列旨在解决一些常见的困扰: 不知道巡检哪些东西 不知道怎么样便捷体检 机器太多体 ...

  3. Sealos AI Proxy 发布!一个平台调用所有大模型,再也不用到处找 API 了

    你是一位开发者,你需要调用各类 AI 模型,每次调用模型,都要在不同的平台间反复横跳,你大概会遇到以下问题: 获取 API Key 流程繁琐:需访问多个厂商的官网,查阅各自的使用文档,并按照规定的步骤 ...

  4. angr-ctf

    angr 的项目地址 https://github.com/jakespringer/angr_ctf angr实战 00 拖到IDA 就是输入正确的指令才能通关 这次试一下用angr来解题 goah ...

  5. 对象存储 AVIF 图片压缩,即将公测!

    2021年8月,腾讯云数据万象以内测方式推出了最前沿的 AVIF 图片压缩服务,可以在图片主观质量相同的情况下大幅降低码率,节省储存空间. 经过3个月时间的内测,我们收集到了很多热心用户的反馈,AVI ...

  6. 有关IOS内存读写冲突

    有关IOS内存读写冲突 在写内存相关代码时,获取已使用内存代码中报错 let hostPort: mach_port_t = mach_host_self() var host_size = mach ...

  7. 常用bat代码

    清除空文件夹 | 清理空文件夹 | 删除空文件夹 @echo off for /f "tokens=*" %%i in ('dir/s/b/ad^|sort /r') do rd ...

  8. Android7 以上https抓包(无需root)- virtualXposed + justTrustMe

    参考资料: https://www.cnblogs.com/boycelee/p/13418371.html 1. virtualXposed下载地址 https://github.com/andro ...

  9. 【转载】Spring Cloud Gateway-过滤器工厂详解(GatewayFilter Factories)

    http://www.imooc.com/article/290816 TIPS 本文基于 Spring Cloud Greenwich SR2 ,理论支持 Spring Cloud Greenwic ...

  10. 用EwoMail开源版搭建邮箱服务器

    介绍: EwoMail是基于Linux的开源邮件服务器,支持一键搭建,集成了众多优秀稳定的组件,是一个快速部署.简单高效.安全稳定的邮件解决方案,支持电脑和手机的客户端,适合个人或邮箱功能需求少的企业 ...