cJSON的那点事儿
JSON(了解)
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
值可以是对象、数组、数字、字符串或者三个字面值(false、null、true)中的一个。值中的字面值中的英文必须使用小写。
数据在键/值对中;数据由逗号分隔;花括号保存对象,也称一个文档对象;方括号保存数组,每个数组成员用逗号隔开,并且每个数组成员可以是文档对象或者数组或者键值对。
cJSON(明确)
cJSON是一个仅有一个.h文件,一个.c文件组成的JSON解析器,它是由纯C(ANSI C89)实现的,跨平台性较好。cJSON是采用链表存储的。
cJSON库在使用的时候只需要如下两步:将cJSON.c(或者库文件)和cJSON.h添加到项目中即可;如果在命令行中进行链接还需要加上-lm表示链接math库。
Cgi程序中,cJSON库一律采用静态编译的方式。
cJSON数据结构
/* cJSON Types: */
#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
/* 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 */
char *valuestring;
/* The item's number, if type==cJSON_Number */
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;
结点数据结构为双向链表,其中string为结点的key; child指向数组或对象的孩子节点
cJSON常用方法(掌握)
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
Hook内存管理函数,默认申请、释放内存函数malloc、free 也可以自定内存管理函数,增加灵活度
extern cJSON *cJSON_Parse(const char *value);
将value字符串转化为cJSON对象
extern char *cJSON_Print(const cJSON *item);
以标准JSON格式输出cJSON对象
extern char *cJSON_PrintUnformatted(const cJSON *item);
以丑化JSON格式输出cJSON对象
extern char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, int fmt);
使用缓冲策略将cJSON实体呈现为文本;prebuffer是对最终大小的猜测;fmt是否丑化(0未格式化,1格式化)
extern void cJSON_Delete(cJSON *c);
释放cJSON内存
extern int cJSON_GetArraySize(const cJSON *array);
获取cJSON数组长度
extern cJSON *cJSON_GetArrayItem(const cJSON *array, int item);
获取cJSON数组单项;item为第几项
extern cJSON *cJSON_GetObjectItem(const cJSON *object, const char *string);
获取对象类型子项,string为key
extern int cJSON_HasObjectItem(cJSON *object,const char *string);
判断是否有key键值是string的项,如果有返回1,否则返回0
extern const char *cJSON_GetErrorPtr(void);
当使用cJSON_Prase()函数解析数据时,如果失败就可以调用该函数,该函数会返回错误的原因
/* 这些是构造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);
向对象中添加键值对
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
将对项的引用附加到指定的数组/对象。当您想要将现有的cJSON添加到新的cJSON中,但又不想破坏现有的cJSON时,请使用此选项
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);
插入到数组,which为插入位置
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
更新数组\对象
#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)
向项中添加键值对
#define cJSON_SetNumberValue(object,val)
修改数值项的值
注意:
对于字符类型的项,没有对应的Set方法,无法确定修改前后内存空间大小是否合适;因此,在修改字符类型的项时先进行删除该项,在重新添加。
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
判断函数
实例
1、 解析一个JSON
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
char text[] = "{\"timestamp\":\"2019-03-03 08:45:57\", \"value\":1}";
int main(int argc, const char *argv[]){
cJSON *json, *json_value, *json_timestamp;
json = cJSON_Parse(text);
if(NULL == json)
{
printf("Error before: [%s]\n", cJSON_GetErrorPtr());
return -1;
}
json_value = cJSON_GetObjectItem(json, "value");
if(json_value->type == cJSON_Number)
{
printf("value: %d\n", json_value->valueint);
}
json_timestamp = cJSON_GetObjectItem(json, "timestamp");
if(json_timestamp->type == cJSON_String)
{
printf("%s\n", json_timestamp->valuestring);
}
cJSON_Delete(json);
return 0;
}
2、 创建一个JSON
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main(void){
char *cjson_str = NULL;
cJSON * root = cJSON_CreateObject();
cJSON * item = cJSON_CreateObject();
cJSON * next = cJSON_CreateObject();
cJSON_AddItemToObject(root, "rc", cJSON_CreateNumber(0));//根节点下添加
cJSON_AddItemToObject(root, "operation", cJSON_CreateString("CALL"));
cJSON_AddItemToObject(root, "service", cJSON_CreateString("telephone"));
cJSON_AddItemToObject(root, "text", cJSON_CreateString("打电话给张三"));
cJSON_AddItemToObject(root, "semantic", item);//root节点下添加semantic节点
cJSON_AddItemToObject(item, "slots", next);//semantic节点下添加item节点
cJSON_AddItemToObject(next, "name", cJSON_CreateString("张三"));//添加name节点
cjson_str = cJSON_Print(root);
printf("first json:\n%s\n", cjson_str);
free(cjson_str);
cJSON_AddStringToObject(next, "number", "13423452334");
cJSON_AddNumberToObject(next, "age", 35);
cJSON_AddBoolToObject(next, "man", 1);
cjson_str = cJSON_Print(root);
printf("second json:\n%s\n", cjson_str);
free(cjson_str);
cJSON_Delete(root);
return 0;
}