需要用到的几个函数:
1、解析JSONJ结构得到cjson对象:cJSON * root=cJSON_Parse(char *buf);
2、获取无格式的json对象:cJSON_PrintUnformatted(cJSON *item)
3、根据键值获取对应的值:cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
假设一串JSON字符串如下:
{“Address”:“111D6FFFFE12459D”,“CommandType”:“010D”,“EndpointId”:“1”,“Command”:{“Operate”:“0”}}
解析如下:
cjson_command com;//此结构体为接收json各个键值的数据
cJSON * root=cJSON_Parse(char *buf);//buf指向cjson字符串数据
c_add =cJSON_GetObjectItem(root,"Address");
strcpy(com.Address,c_add->valuestring);
cJSON * c_ctype =NULL;
c_ctype =cJSON_GetObjectItem(root,"CommandType");
strcpy(com.CommandType,c_ctype->valuestring);
cJSON * c_Epid =NULL;
c_Epid =cJSON_GetObjectItem(root,"EndpointId");
strcpy(com.Endpointid,c_Epid->valuestring);
cJSON * c_Com =NULL;
c_Com =cJSON_GetObjectItem(root,"Command");
if(c_Com == NULL)
{
u3_printf("no command\r\n");
}else{
cJSON * c_Ope =NULL;
c_Ope =cJSON_GetObjectItem(c_Com,"Operate");
if(c_Ope == NULL)
{
u3_printf("no Operate!\r\n");
}else
{
strcpy(com.Operate,c_Ope->valuestring);
u3_printf("Operate:%s\r\n",com.Operate);
}
cJSON_Delete(root);
注意:
我的例子里 json字符串的值全为char类型的,可根据实际情况设置变量,例如c_ctype->valuestring可以为valueint、valuedouble。
1、第一类:{
“num”:10000,
“stu”:[
{
“age”:“1”,
“name”:“张三”
},
{
“age”:“2”,
“name”:“李四”
}
],
}
这类主要是有一项是数组类型,里面有多个数组元素是json格式的字符串,其他的和普通cjson解析一样,到数组那一个对象的时候:
c_items = cJSON_GetObjectItem(values,"stu");
if(c_items != NULL)
{
//
}else
return 0;
items_size =cJSON_GetArraySize(c_items);
if(items_size == 0)
{
return 0;
}
cJSON *arr_items = c_items->child;
for(n=0; n<items_size; n++)
{
strcpy(age,cJSON_GetObjectItem(arr_items,"age")->valuestring);
strcpy(name,cJSON_GetObjectItem(arr_items,"name")->valuestring);
arr_items = arr_items->next;//跳到下一个元素
}
cJSON_Delete(root);
2、第二类:一个字符串里面有多个数组对象,每个数组里面的值如下所示:
“sleepData”: {
“2020-04-22”: {
“lightSleep”: [
“2020-04-22 04:00:00_2020-04-22 04:30:00”,
“2020-04-22 04:30:00_2020-04-22 05:00:00”,
“2020-04-22 05:00:00_2020-04-22 05:30:00”,
“2020-04-22 05:30:00_2020-04-22 06:00:00”
],
“deepSleep”: [
“2020-04-22 00:00:00_2020-04-22 00:30:00”,
“2020-04-22 00:30:00_2020-04-22 01:00:00”,
“2020-04-22 01:30:00_2020-04-22 02:00:00”
]
},
“2020-04-21”: {
“lightSleep”: [
“2020-04-22 04:00:00_2020-04-22 04:30:00”,
“2020-04-22 04:30:00_2020-04-22 05:00:00”,
“2020-04-22 05:00:00_2020-04-22 05:30:00”
]
}
}
items_size = cJSON_GetArraySize(c_lsleep);
for(icnt = 0; icnt < items_size; icnt++)
{
c_items=cJSON_GetArrayItem(c_lsleep, icnt);//获取数组里面的元素
if(c_items ==NULL)
{
continue;
}
//strcpy();
}
其他跟之前的类似。
cJSON *root,*fmt;
root=cJSON_CreateObject();
cJSON_AddStringToObject(root,"Address",sta.Address);
cJSON_AddStringToObject(root,"EndpointId",sta.Endpointid);
cJSON_AddItemToObject(root, "State", fmt=cJSON_CreateObject());
cJSON_AddStringToObject(fmt,"State", sta.State);
cJSON_AddStringToObject(root,"StateType",sta.StateType);
cJSON_AddNumberToObject(root,"DeviceType",1101);
char *out=cJSON_PrintUnformatted(root);
if(out)
{
strncpy((char*)sta_buff,out,strlen(out));
sta_flag=1;
free(out);
}
合成结果如下:
{
“Address”: “1234567890ABCDEF”,
“EndpointId”: “1”,
“State”: {
“State”: “1”
},
“StateType”: “020D”,
“DeviceType”: 1101
}
注意:1、在合成的时候,发现不能打印出来的情况,无法合成cjson字符串,程序出现跑飞的情况。原因是数据长度过大,堆栈大小不够,导致堆栈溢出。办法是startup_stm32f10x_md.s中调整堆栈大小即可。
2、出现内存错误,原因有可能你的内存申请和释放函数不兼容,在cjson.c文件里把你自己的替换掉,主要是这两块地方:
void *(*cJSON_malloc)(size_t sz) = myFwl_Malloc;
void (*cJSON_free)(void *ptr) = myFwl_Free;
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = myFwl_Malloc;
cJSON_free = myFwl_Free;
return;
}
//cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn: malloc;
//cJSON_free = (hooks->free_fn)?hooks->free_fn: free;
//cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:Fwl_MallocAndTrace;
//cJSON_free = (hooks->free_fn)?hooks->free_fn:Fwl_FreeAndTrace;
cJSON_malloc = myFwl_Malloc;
cJSON_free = myFwl_Free;
}