STM32学习笔记之Cjson的使用

普通解析

需要用到的几个函数:
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;
}

你可能感兴趣的:(STM32学习笔记之Cjson的使用)