cJSON保姆级教程
努力成为大佬!
JSON简介
JSON 全称 JavaScript Object Notation,即 JS对象简谱,是一种轻量级的数据格式。
它采用完全独立于编程语言的文本格式来存储和表示数据,语法简洁、层次结构清晰,易于人阅读和编写,同时也易于机器解析和生成,有效的提升了网络传输效率。
JSON对象是一个无序的"名称/值"键值对的集合:
- 以"
{
“开始,以”}
"结束,允许**「嵌套使用」**; - 每个**「名称和值成对出现」**,名称和值之间使用"
:
"分隔; - 键值对之间用"
,
"分隔 - 在这些字符前后允许存在无意义的空白符;
对于键值,可以有如下值:
-
一个新的**「json对象」**
-
「数组」:使用"
[
“和”]
"表示 -
「数字」:直接表示,可以是整数,也可以是浮点数
-
「字符串」:使用引号
"
表示 -
「字面值」:false、null、true中的一个(必须是小写)
示例:
-
{ "students" : [ { "name" : "XiaoMing", "age" : 10, "learning" : true }, { "name" : "XiaoHong", "age" : 11, "learning" : false } ] }
cJSON介绍
cJSON是一个使用C语言编写的JSON数据解析器,具有超轻便,可移植,单文件的特点,使用MIT开源协议。
cJSON项目托管在Github上,仓库地址如下:
https://github.com/DaveGamble/cJSON
可以看到里面的文件比较多,其中cJSON的源码文件只有两个:
-
cJSON.h
-
cJSON.c
使用的时候,只需要将这两个文件复制到工程目录,然后包含头文件
cJSON.h
即可,如下:#include "cJSON.h"
基本使用操作
关键数据结构
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
设计为一个结点结构体,有前后结点和孩子结点,type是该结点存放的数据类型,后面依次为数据存储。
设计思想
**根据上面结构体定义,设计的主要思想就是链表。**通过前后结点遍历,同时使用child*支持嵌套。
首先,它不是将一整段JSON数据抽象出来,而是将其中的一条JSON数据抽象出来,也就是一个键值对,用上面的结构体 strcut cJSON 来表示;
其次,一段完整的JSON数据中由很多键值对组成,并且涉及到键值对的查找、删除、添加,所以使用链表来存储整段JSON数据,如上面的代码所示:
next指针:指向下一个键值对
prev指针:指向上一个键值对
最后,因为JSON数据支持嵌套,所以一个键值对的值会是一个新的JSON数据对象(一条新的链表),也有可能是一个数组,方便起见,在cJSON中,数组也表示为一个数组对象,用链表存储,所以:
在键值对结构体中,当该键值对的值是一个嵌套的JSON数据或者一个数组时,由child指针指向该条新链表。
JSON数据解析
解析JSON数据的过程,其实就是剥离一个一个链表节点(键值对)的过程。
用于**「将字符串解析成json对象」**,若失败则返回NULL。
cJSON *cJSON_Parse(const char *value);
用于**「获取json对象中的某个节点」**,若失败,返回NULL,成功则返回该节点对象。
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
用于释放json对象相关内存。
void cJSON_Delete(cJSON *c);
如果JSON数据的值是数组,可以通过下面接口获取JSON 数组
大小和数组里面的JSON 对象
int cJSON_GetArraySize(