JSON解析与创建

什么是json

这是一条json

{"name":"hany","age":18}

一对{}就是一个JSON object
object里的"mane" "age"被称为key name,"hany" 18被称为key value

KEY name是一个字符串

下面重点说一下KEY value 的可选类型

value是INT型

{"age":18}

value是DOUBLE型

{"height":180.1}

value是STRING型

{"name":"hany"}

value是ARRAY型

{"module":[]}

value是OBJECT

{"people":{"name":"hany"}}

JSON的解析与创建

方法一:直接使用字符串操作

解析

使用C库函数strstr判断有无关心的关键字即可。

#include <stdio.h>
#include <string.h>

const char *rpc_cmd = "{"id":5,"action":"led_on"}";
if (strstr(rpc_cmd, "led_on"))
{
	printf("open led");
}

创建

先写出这条json的格式,再使用C库函数snprintf对其进行value值填充即可

const char *query_did_format = "{\"id\":%d,\"method\":\"local.query_did\", \"params\":\"\"}";
char rpc_buf[64] = {0};
snprintf(rpc_buf, sizeof(rpc_buf), query_did_format, rand());

优点:操作简单,节省资源

缺点:处理复杂协议就显得很麻烦

方法二:使用CJSON

解析

目标

static const char *monitor_without_hd = "{\n\t\t\"name\": \"lame monitor\",\n\t\t\"resolutions\":\t[{\n\t\t\t\"width\":\t640,\n\t\t\t\"height\":\t480\n\t\t}]\n}";

/*return 1 if the monitor supports full HD , 0 otherwise*/
static int supports_full_hd(const char * const monitor)
{
	int status = 0;
	/*首先调用cJSON_Parse,解析JSON数据包。该函数会malloc出一块内存,使用完毕后要手动释放*/
	cJSON *monitor_json = cJSON_Parse(monitor);
	if (monitor_json == NULL)
	{
		status = 0;
		goto end;
	}
	
	/*在JSON Object中,查找 key name 为 “name”的 key, 找到后返回其 key value */
	const cJSON *name = cJSON_GetObjectItemCaseSensitive(monitor_json, "name");
	/*判断 key value是不是字符串,并且字符串不为空*/
	if (cJSON_IsString(name) && (name->valuestring != NULL))
	{
		printf("checking monitor \"%s\", name->valuestring);
	}
	/*在JSON Object中,查找key name 为"resolution"的key,找到后返回其值*/
	const cJSON *resolutions = cJSON_GetObjectItemCaseSensitive(monitor_json, "resolutions");
	/*判断resolution是不是数组*/
	if (!cJSON_IsArray(resolutions))
	{
		goto end;
	}
	const cJSON *resolution = NULL;
	/*在resolutions数组中,遍历每一个JSON OBJECT */
	cJSON_ArrayForEach(resolution, resolutions)
	{
		cJSON *width = cJSON_GetObjectItemCaseSensitive(resolution, "width");
		cJSON *height = cJSON_GetObjectItemCaseSensitive(resolution, "height");
		
		if (!cJSON_IsNumber(width) || !cJSON_IsNumber(height))
		{
			status = 0;
			goto end;
		}
		
		if (width->valueint == 1920 && width->valueint == 1080)
		{
			status = 1;
			goto end;
		}
	}
end:
	/*释放cJSON_Parse分配出来的内存*/
	cJSON_Delete(monitor_json);
	return status;
}

创建

目标

格式化的JSON
{
    "name": "Awesome 4K",
    "resolutions": [
        {
            "width": 1280,
            "height": 720
        },
        {
            "width": 1920,
            "height": 1080
        },
        {
            "width": 3840,
            "height": 2160
        }
    ]
}
未格式化的JSON

{"name": "Awesome 4K","resolutions": [{"width": 1280,"height": 720},{"width": 1920, "height": 1080},{"width": 3840,"height": 2160}]}

代码生成格式化的JSON

//NOTE: Returns a heap allocated string, you are required to free it after use.
void create_monitor_with_helpers(void)
{
    const unsigned int resolution_numbers[3][2] = {
        {1280, 720},
        {1920, 1080},
        {3840, 2160}
    };
    char *string = NULL;
    cJSON *resolutions = NULL;
    size_t index = 0;
	
	/*创建{}。cJSON_CreateObject执行后,会申请一块内存,使用完毕后,需要手动释放*/
    cJSON *monitor = cJSON_CreateObject();
	
	/*{"name": "Awesome 4K"}*/
    if (cJSON_AddStringToObject(monitor, "name", "Awesome 4K") == NULL)
    {
        goto end;
    }
	
	/*{"name": "Awesome 4K","resolutions":[]}*/
    resolutions = cJSON_AddArrayToObject(monitor, "resolutions");
    if (resolutions == NULL)
    {
        goto end;
    }

	//对数组进行赋值
    for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)
    {
		//创建{}
        cJSON *resolution = cJSON_CreateObject();
		//加入键值对width
        if (cJSON_AddNumberToObject(resolution, "width", resolution_numbers[index][0]) == NULL)
        {
            goto end;
        }
		//加入键值对height
        if (cJSON_AddNumberToObject(resolution, "height", resolution_numbers[index][1]) == NULL)
        {
            goto end;
        }
		//将当前OBJECT 加入到数组
        cJSON_AddItemToArray(resolutions, resolution);
    }
	
	//对创建好的JSON进行格式化。cJSON_Print执行后会提请一块内存,使用完毕后,需要手动释放
	string = cJSON_Print(monitor);
	if (string == NULL)
	{
		fprintf(stderr, "Failed to print monitor.\n");
	}
	else
	{
		cJSON_free(string);
	}

end:
	cJSON_Delete(monitor);
}

优点:能适用任何复杂的JSON协议,方便动态扩展键值对

缺点:会用到大量的动态内存,需要注意内存泄露问题;非线程安全

cJSON_Parse cJSON_CreateObject 要用 cJSON_Delete 释放
cJSON_Print cJSON_PrintUnformatted 要用 cJSON_free 释放

方法三:CJsonObject

简介

  • CJsonObject是基于cJSON全新开发一个C++版的JSON库,CJsonObject的最大优势是轻量,简单好用,开发效率极高。
  • CJsonObject只有4个文件,拷贝到自己代码里源码级集成即可,无须编译成库,且跨平台和编译器。
  • 与大部分json解析库访问多层嵌套json非常麻烦不同,CJsonObject对多层嵌套json的读取和生成使用非常简单。
  • 支持线程安全
  • 更多内容请移步作者BLOG:https://www.cnblogs.com/bwar/p/11294452.html

JSON解析与创建

上一篇:OKhttp的理解-RealConnectionPool


下一篇:Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):