什么是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