cJSON,目前来说,就只有两个文件,一个cJSON.c 一个cJSON.h文件。工程里添加这两个文件就可以使用CJson构造或者解析相应的文件。
cJSON * cJSON_CreateObject();
创建一个json对象,返回一个cJSON结构体类型的指针。
cJSON *cJSON_CreateArray();
创建一个数组对象,返回一个cJSON结构体类型的指针。
cJSON *cJSON_CreateString(const char *string);
创建一个字符串对象,传入一个char *类型的字符串,返回一个cJSON结构体类型的指针。
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
向数组对象中添加一个元素,传入参数array为cJSON *结构体类型的指针,为数组对象; item为添加入数字对象中的对象指针。
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
向json对象中添加一对元素,object为json对象,string为加入一对元素中的name,item为加入一对元素中的value。
cJSON *cJSON_Parse(const char *value);
解析一个json串,传入一个json格式的字符串,返回一个cJSON *类型的结构体指针。
char *cJSON_Print(cJSON *item);
将一个cJSON结构体代表的json对象转换为一个json格式的字符串。
void cJSON_Delete(cJSON *c);
释放一个cJSON对象所占用的内存空间。
构造一个JSON格式的字符串如下所示:
{
"MsgType":1,
"DeviceID":"s123",
"RegNum":6,
"data":
[
{ "Reg": "vcc", "Val": 12},
{ "Reg": "temp", "Val ": 25},
{ "Reg": "hump", "Val ": 40},
{ "Reg": "voice", "Val ": 60},
{ "Reg": "lvdt", "Val ": 80},
{ "Reg": "door", "Val ": 1}
]
}
Json写入:
1. 创建json root对象分配空间
2. 向root对象中添加 item item可以是item 、object 、array
1、item:用cJSON_CreateString() cJSON_CreateNumber()创建的item
2、object:先创建json对象分配空间 可以向当前对象中添加item
3、array:先创建array 分配空间 然后向当前的array添加object
3.生成json root对象 的json字符串
4.释放json root空间。
代码如下所示:
unsigned RegVal[]={12,25,40,60,80,1};
/****************************构造一个json格式字符串******************************************/
void create_JsonStr(void)
{
cJSON *json;
cJSON *Arrayobj;
cJSON *Array;
char *JsonStr;
char *pcStr;
int i=0;
json = cJSON_CreateObject(); //创建一个cjson对象,返回一个cJSON结构体类型的指针。
cJSON_AddItemToObject(json,"MsgType",cJSON_CreateNumber(1));
cJSON_AddItemToObject(json,"DeviceID",cJSON_CreateString("s123"));
cJSON_AddItemToObject(json,"RegNum",cJSON_CreateNumber(6));
cJSON_AddItemToObject(json,"data", Array = cJSON_CreateArray()); //创建一个Array数组对象 并向cjson对象中添加这个数组对象
for(i=0; i <6; i++)
{
cJSON_AddItemToArray(Array,Arrayobj=cJSON_CreateObject()); //创建一个Arrayobj对象,并将此对象添加到Array数组对象中
pcStr=RegTypeString[i];
cJSON_AddItemToObject(Arrayobj, "Reg", cJSON_CreateString(pcStr) ); //向Arrayobj对象中添加元素
cJSON_AddItemToObject(Arrayobj, "Val", cJSON_CreateNumber(RegVal[i]) ); //向Arrayobj对象中添加元素
}
JsonStr = cJSON_PrintUnformatted(json); //获取字符串指针 无格式
//JsonStr = cJSON_Print(cjson); //获取字符串指针 有格式
printf("%s",JsonStr);
cJSON_Delete(json); //删除主节点对象
free(JsonStr);
}
/****************************解析json格式字符串******************************************/
void parse_JsonStr(char *JsonStr)
{
cJSON *json;
cJSON *item;
cJSON *Arrayobj;
cJSON *Array;
char *pcStr;
int i=0;
cJSON *json = cJSON_Parse(jsonStr);
if(NULL == json)
{
printf("parse Err!");
return;
}
item=cJSON_GetObjectItem(json, "MsgType");
printf("MsgType=%d \n",item->valueint);
item=cJSON_GetObjectItem(json, "DeviceID");
printf("DeviceID=%s \n",item->valuestring);
item=cJSON_GetObjectItem(json, "RegNum");
printf("RegNum=%d \n",item->valueint);
Array = cJSON_GetObjectItem(json, "data");
icount=cJSON_GetArraySize(Array);
if(icount != item->valueint)
{
printf("Arry Buff err! \n");
}
for(i=0; i < icount; i++)
{
Arrayobj = cJSON_GetArrayItem(Array, i);
item=cJSON_GetObjectItem(RegTypeArray, "Reg");
printf("Reg=%s ",item->valuestring);
item=cJSON_GetObjectItem(RegTypeArray, "Val");
printf("Reg=%s \n",item->valueint);
}
cJSON_Delete(cjson); //删除主节点对象
}
1、cJSON_Print也是分配内存的,需要手动去释放掉,需要和free()配套使用。
2、 cJSON_PrintUnformatted(json); 和 cJSON_Print(cjson); 都是获取字符串指针 一种是无格式,一种是有格式。有格式生成的人字符串添加了很多空格盒换行符有利于阅读,但不利于数据传输。推荐使用无格式传输。
3、对于一个CJSOn数据树,只需要删除主节点,子节点就会主动释放。但是如果子节点没有包含在主节点内,需要主动释放,要不然会造成内存泄漏。使用cJSON_Delete(); //删除节点对象