一.JSON格式简述

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。(来自“开源中国”资料)。

 

cJSON从名字可知,整个项目都是以极标准的C来写的,意思说,可以跨各种平台使用了。cJSON是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器。

 

cJSON 开源项目位置:点击打开链接

更加详细的解释和示例请查看 http://www.json.org/ 主页。

 

cJSON,目前来说,就只有两个文件,一个cJSON.c 一个cJSON.h文件。使用的时候,自己创建好一个main.c文件后,将头文件include进去。

如果是在linux pc上,请使用以下命令进行编译:

gcc *.c cJSON.c -lm

记得编译时末尾链接libm库。

 

二.JSON结构体

熟悉使用cJSON库函数可从cJSON结构体入手,cJSON结构体如下所示:

 

几点说明

1.cJOSN结构体为一个双向列表,并可通过child指针访问下一层。

2.type变量决定数据项类型(键的类型),数据项可以是字符串可以是整形,也可以是浮点型。如果是整形值的话可从valueint,如果是浮点型的话可从valuedouble取出,以此类推。

3.string可理解为节点的名称,综合此处的第2点可理解为“键”的名称。

4.如果是对象或者数组,采用的是双向链表来实现,链表中的每一个节点表示数组中的一个元素或者对象中的一个字段。其中child表示头结点,next、prev分别表示下一个节点和前一个节点。valuestring、valueint、valuedouble分别表示字符串、整数、浮点数的字面量。

 

cJSON作为Json格式的解析库,其主要功能无非就是构建和解析Json格式了,用途就是一端将要发送的数据已cjson形式封装,然后发送,另一端收到此数据后,还是按cjson形式解析,就得到想要的数据了。

 

三.JSON各个API的使用

①:

#define cJSON_False (1 << 0)

#define cJSON_True (1 << 1)

#define cJSON_NULL (1 << 2)

#define cJSON_Number (1 << 3)

#define cJSON_String (1 << 4)

#define cJSON_Array (1 << 5)

#define cJSON_Object (1 << 6)

 

#define cJSON_IsReference 256

#define cJSON_StringIsConst 512

这些宏定义是对结构体type的值定义,处理时只需要将type的值&255进行位运算,即可得到json里储存的数据类型。

②:

/* The cJSON structure: */

typedef struct cJSON {

struct cJSON *next,*prev; //同一级元素使用链表存储

struct cJSON *child; //如果是一个object或array的话,child为第一个儿子的指针

int type; //value的类型

char *valuestring; //如果这个value是字符串类型,则此处为字符串值

int valueint; //如果是数字的话,整数值

double valuedouble; //如果是数字的话,浮点数值

char *string; //json对象的名称

} cJSON;

③:

cJSON内存管理:

hook管理函数:

在 c 语言中内存一般是 malloc 和 free 的。

为了方便用户自由的管理内存, cjson 使用 Hook 技术来让使用者可以自定义内存管理函数。

即用户自定义 malloc 和 free.

具体实现方式可以参考下面的代码, 默认使用系统的 malloc 和 free 函数, 用过 cJSON_InitHooks 函数可以替换成用户自定义的 malloc 和 free 函数。

typedef struct cJSON_Hooks {

void *(*malloc_fn)(size_t sz);

void (*free_fn)(void *ptr);

} cJSON_Hooks;

 

/* 对cJSON提供的分配,重分配,释放内存初始化函数 */

extern void cJSON_InitHooks(cJSON_Hooks* hooks);

④:各种API调用

/* 将普通的json字符串处理成json对象,注意:使用完后需要将json指针释放*/

extern cJSON *cJSON_Parse(const char *value);

 

/*将cjson格式的数据,转换为普通字符串的新式,虽然json格式的数据也是一个字符串的样子,但这时候还是无法当成普通的字符串使用,注意:使用完后需要将json指针释放*/

extern char *cJSON_Print(cJSON *item);

 

/*将cjson格式的数据,以没有格式的形式转换成普通的字符串:也就是字符串中间不会有"\n" "\t"之类的东西存在,注意:使用完后需要将json指针释放*/

extern char *cJSON_PrintUnformatted(cJSON *item);

 

/*使用缓冲策略将cJSON实体呈现为文本。预缓冲是对最终大小的猜测。猜测良好可以减少重新分配。fmt=0给出未格式化,=1给出格式化*/

extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt);

 

/*释放内存*/

extern void cJSON_Delete(cJSON *c);

 

/*获取数组里面元素的个数,指针array是一个指向数组的对象*/

extern int cJSON_GetArraySize(cJSON *array);

 

/*获取数组里面的元素,这个元素也可能是对象,item是对应元素的下标*/

extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);

 

/*获取键值内容(对象里面的对象),用一个新的 json 指针,指向该对象*/

extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);

 

/*判断是否有key键值是string的项,如果有返回1,否则返回0*/

extern int cJSON_HasObjectItem(cJSON *object,const char *string);

 

 

/*当使用cJSON_Prase()函数解析数据时,如果失败就可以调用该函数,该函数会返回错误的原因*/

extern const char *cJSON_GetErrorPtr(void);

/* 这些是构造json的一些API */

extern cJSON *cJSON_CreateNull(void); //创建一个空对象,暂时保留以后可能要用到

extern cJSON *cJSON_CreateTrue(void); //创建一个true的对象

extern cJSON *cJSON_CreateFalse(void); //创建一个false的对象

extern cJSON *cJSON_CreateBool(int b); //创建一个bool对象

extern cJSON *cJSON_CreateNumber(double num); //创建一个数字类型的对象

extern cJSON *cJSON_CreateString(const char *string); //创建一个字符串类型的对象

extern cJSON *cJSON_CreateArray(void); //创建一个数组类型的对象

extern cJSON *cJSON_CreateObject(void); //创建一个根对象,它是cjson格式的头结点

 

/* 创建数组其中里面可以设定为不同的数据类型*/

extern cJSON *cJSON_CreateIntArray(const int *numbers,int count); //整形

extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); //浮点型

extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); //double型

extern cJSON *cJSON_CreateStringArray(const char **strings,int count); //字符串类型

 

/* 向数组中添加对象*/

extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);

 

/*向对象中添加键值对,值的类型与相关函数有关*/

extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

 

/*当字符串肯定是const(即一个文字,或者与常量一样好),并且肯定能在cJSON对象中存活下来时,可以使用这个*/

extern void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item);

 

/* 将对项的引用附加到指定的数组/对象。当您想要将现有的cJSON添加到新的cJSON中,但又不想破坏现有的cJSON时,请使用此选项 */

extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);

extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);

 

/* 从数组/对象中删除/分离项 */

extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);

extern void cJSON_DeleteItemFromArray(cJSON *array,int which);

extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);

extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);

/* 更新数组项 */

extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem);//右移

extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);

extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);

 

/* 复制一个cJSON项 */

extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);

/* Duplicate将在新的内存中创建与传递的cJSON相同的新项需要释放。递归!=0,它将复制与项连接的任何子节点。item->next和->prev指针从Duplicate返回时总是为0。*/

 

/* ParseWithOpts允许您要求(并检查)JSON终止为空,并检索到解析的最后一个字节的指针 */

/* 如果在return_parse_end中提供ptr,并且解析失败,那么return_parse_end将包含一个指向错误的指针。如果没有,那么cJSON_GetErrorPtr()就可以了。 */

extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);

 

extern void cJSON_Minify(char *json);

 

/* 用于快速创建内容的宏. */

#define cJSON_AddNullToObject(object,name)

#define cJSON_AddTrueToObject(object,name)

#define cJSON_AddFalseToObject(object,name)

#define cJSON_AddBoolToObject(object,name,b)

#define cJSON_AddNumberToObject(object,name,n)

#define cJSON_AddStringToObject(object,name,s)

 

/*当分配一个整数值时,它也需要传播到valuedouble */

#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))

#define cJSON_SetNumberValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))

 

/*用于迭代数组的宏 */

#define cJSON_ArrayForEach(pos, head) for(pos = (head)->child; pos != NULL; pos = pos->next)

 

 

先分支再综合,先写子类在写父类

 

 

 

10-06 19:29