cJSON_PrintUnformatted数据结构转换为JSON字符串无法输出问题及解决方法

cJSON_PrintUnformatted数据结构转换为JSON字符串无法输出问题及解决方法

1. 问题现象

在这里插入图片描述

2. 问题原因

在这里插入图片描述
跟踪调试发现 cJSON大量调用malloc来申请内存,怪不得cjson例子里用完之后要delete对象。原来是要释放内存。STM32里面malloc是在heap也就是堆里面申请内存,因此Heap_Size太小了会导致malloc返回失败,从而导致cJSON_Print(或者cJSON_PrintUnformatted)返回NULL。

3. 解决方法

增加Heap_Size的大小 (>10k,效果会更好),问题就解决了。

char *json_data = cJSON_PrintUnformatted(TCP); //JSON数据结构转换为JSON字符串
在这里插入图片描述

在这里插入图片描述

4. 示例代码

void test_cjson(void)
{
	double	grade[4]={66.51,118.52,61.53,128.54};
		int 	time[4]={123,456,789,150};
		
		cJSON *TCP = cJSON_CreateObject();				//创建一个对象
		
		cJSON_AddStringToObject(TCP,"name","MQ");		//添加字符串 
		cJSON_AddNumberToObject(TCP,"age",25);			//添加整型数字 
		cJSON_AddNumberToObject(TCP,"height",183.52);	//添加浮点型数字
		cJSON_AddFalseToObject(TCP,"gender");			//添加逻辑值false
		 
	
		cJSON *ADD	= cJSON_CreateObject(); 			//创建一个对象
		cJSON_AddStringToObject(ADD,"country","China"); //添加字符串 
		cJSON_AddNumberToObject(ADD,"zip-code",123456); //添加整型数字
		cJSON_AddItemToObject(TCP,"address",ADD);
		
		cJSON *SUB	= cJSON_CreateArray();				//创建一个数组
		cJSON_AddStringToObject(SUB,"","政治");		//添加字符串到数组
		cJSON_AddStringToObject(SUB,"","数学");
		cJSON_AddStringToObject(SUB,"","英语");
		cJSON_AddStringToObject(SUB,"","专业课");
		cJSON_AddItemToObject(TCP,"subject",SUB);		//添加数组到对象
		
		cJSON *TIM	= cJSON_CreateIntArray(time,4); 	//创建一个整型数组
		cJSON_AddItemToObject(TCP,"time",TIM);
		
		cJSON *GRA	= cJSON_CreateDoubleArray(grade,4); //创建一个双浮点型数组
		cJSON_AddItemToObject(TCP,"grade",GRA);
		
		cJSON *STU	= cJSON_CreateArray();			//创建一个数组
		
		cJSON *Z3  = cJSON_CreateObject();			//创建一个对象
		cJSON_AddStringToObject(Z3,"name","张三");	//添加字符串 
		cJSON_AddNumberToObject(Z3,"age",24);		//添加整型数字 
		cJSON_AddTrueToObject(Z3,"gender"); 		//添加逻辑值 
		cJSON_AddItemToArray(STU,Z3);				//添加对象到数组中 
		
		cJSON *L4  = cJSON_CreateObject();			//创建一个对象
		cJSON_AddStringToObject(L4,"name","李四");	//添加字符串 
		cJSON_AddNumberToObject(L4,"age",25);		//添加整型数字 
		cJSON_AddTrueToObject(L4,"gender"); 		//添加逻辑值 
		cJSON_AddItemToArray(STU,L4);				//添加对象到数组中
		
		cJSON *W5  = cJSON_CreateObject();			//创建一个对象
		cJSON_AddStringToObject(W5,"name","王五");	//添加字符串 
		cJSON_AddNumberToObject(W5,"age",26);		//添加整型数字 
		cJSON_AddTrueToObject(W5,"gender"); 		//添加逻辑值 
		cJSON_AddItemToArray(STU,W5);				//添加对象到数组中
		
		cJSON_AddItemToObject(TCP,"student",STU);	//添加数组到对象中
	
		char *json_data = cJSON_PrintUnformatted(TCP); //JSON数据结构转换为JSON字符串
		printf("%s\n",json_data);//输出字符串
		free(json_data);
		cJSON_Delete(TCP);//清除结构体
		
}

5. 特别声明

程序最后一定要cJSON_Delete 删除对象。

还有cJSON_Print(或者cJSON_PrintUnformatted)会一直不停申请内存,所有调用完之后一定要free释放,否则多次调用后一样会内存溢出。导致后面的cJSON_Print(或者cJSON_PrintUnformatted)会申请不到内存。

char *json_data = cJSON_PrintUnformatted(TCP); //JSON数据结构转换为JSON字符串
		printf("%s\n",json_data);//输出字符串
		free(json_data);
		cJSON_Delete(TCP);//清除结构体

6. json在线解析工具

https://www.sojson.com/simple_json.html

https://www.json.cn/

参考资料:
CJSON库中,cJSON_PrintUnformatted()函数内存泄漏相关问题
https://blog.csdn.net/weixin_38537639/article/details/119932978?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-4.no_search_link&spm=1001.2101.3001.4242.4

### 回答1: cjson_printunformatted 是一个 CJSON 库中的函数,用于将 CJSON 对象以未格式化的形式打印到输出流中,其中 CJSON 是一个用于解析和生成 JSON 数据的 C 语言库。 该函数的声明如下: ```c void cjson_printunformatted(cJSON *item) ``` 其中,参数 item 是要打印的 CJSON 对象的指针。该函数将 CJSON 对象以未格式化的形式打印到标准输出流中。 在使用该函数之前,需要先创建一个 CJSON 对象并将其填充为所需的 JSON 数据结构。例如,以下代码创建了一个包含一个数组和两个键值对的 JSON 对象,并使用 cjson_printunformatted 函数将其打印到标准输出流中: ```c cJSON *root = cJSON_CreateObject(); cJSON_AddItemToObject(root, "numbers", cJSON_CreateIntArray(numbers, 3)); cJSON_AddItemToObject(root, "key1", cJSON_CreateString("value1")); cJSON_AddItemToObject(root, "key2", cJSON_CreateString("value2")); cjson_printunformatted(root); ``` 输出结果如下: ``` {"numbers":[1,2,3],"key1":"value1","key2":"value2"} ``` 需要注意的是,未格式化的打印输出不包含任何空格或换行符,因此输出结果在可读性方面可能略差。如果需要更好的可读性,可以考虑使用 cjson_Print 函数或其他类似函数。 ### 回答2: cjson_printunformatted是一个C语言中的函数,用于将一个JSON对象打印成一个字符串,但不会格式化输出。这意味着输出字符串中不会包含空格、制表符或换行符等空白字符。 在使用cjson库(一个C语言中的JSON解析器)解析完一个JSON对象后,我们可以使用cjson_printunformatted将其打印成一个字符串,以方便在程序中进行后续的处理。 举个例子,假设我们解析了如下的JSON字符串: { "name": "Tom", "age": 18, "address": { "province": "Guangdong", "city": "Shenzhen" } } 通过cjson库中的函数,我们可以将其解析成一个JSON对象。然后,我们可以使用cjson_printunformatted将其打印成一个字符串: char *json_str = cjson_printunformatted(json); // json为解析后的JSON对象 printf("%s\n", json_str); 此时,输出字符串将是以下形式: {"name":"Tom","age":18,"address":{"province":"Guangdong","city":"Shenzhen"}} 可以看到,该字符串中没有包含空格、制表符或换行符等空白字符。 使用cjson_printunformatted输出字符串虽然不够易读,但其字符串长度通常会更短,因此在网络传输或存储时比较适合使用。如果需要更易读的格式化输出,可以使用cjson_print函数。 ### 回答3: cjson_printunformatted 函数是 cjson 库中的一个输出函数,其作用是将 cjson 结构体转换JSON 格式的字符串,并打印出来。不同于 cjson_print 和 cjson_pretty,cjson_printunformatted 输出字符串没有进行任何格式化,即没有添加任何缩进和换行符,因此该函数输出字符串比较紧凑,适合用于网络传输和文件存储。 cjson_printunformatted 函数的函数原型为: ```c void cjson_printunformatted(const cJSON *item); ``` 该函数的参数是一个 cJSON 结构体指针,表示要输出JSON 数据。 cjson_printunformatted 函数实现时采用了递归方式,从 cJSON 结构体的根节点开始遍历整个 JSON 数据,在遍历过程中通过字符串操作函数构建输出字符串,最后将字符串打印出来。 使用 cjson_printunformatted 输出 JSON 数据时需要注意以下事项: 1. 要确保输出的 cJSON 结构体必须是一个合法的 JSON 数据,否则输出字符串可能不符合 JSON 格式要求。 2. 由于 cjson_printunformatted 输出字符串没有进行任何格式化,因此字符串长度可能会很长,需要确保输出字符串不会超出系统的限制。 3. 在使用 cjson_printunformatted 输出 JSON 数据时要注意数据的保密性和完整性,避免出现数据泄露或者篡改。 总之,cjson_printunformatted 函数是 cjson 库中一个十分实用的输出函数,可以将 cJSON 结构体转换成紧凑的 JSON 格式的字符串,并打印出来,方便数据传输和存储。但是在使用时需要根据具体情况进行数据保密性和完整性的考虑,确保数据的安全。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值