cJSON的使用
1 安装cJSON
github地址:https://github.com/DaveGamble/cJSON.git
- 下载完成后进入cJSON目录,执行下面命令生成Makefile文件 - mkdir build
 cd build
 cmake ..
 
- 执行下面命令安装cJSON库 - make install
 - 默认将头文件安装到/usr/local/include/cjson路径下
- 默认将链接库安装到/usr/local/lib路径下
 
- 默认将头文件安装到
- 一些CMake选项介绍 - 选项 - 功能 - 默认值 - -DENABLE_CJSON_TEST- 开启编译tests - On - -DENABLE_CJSON_UTILS- 开启编译cJSON_Utils - Off - -DENABLE_TARGET_EXPORT- 开启CMake目标导出 - On - -DENABLE_CUSTOM_COMPILER_FLAGS- 开启自定义编译选项 - On - -DENABLE_VALGRIND- 使用valgrind运行tests - Off - -DENABLE_SANITIZERS- 使用AddressSanitizer和UndefinedBehaviorSanitizer编译cJSON - Off - -DENABLE_SAFE_STACK- 开启SafeStack工具检测(目前只能在Clang编译器上工作) - Off - -DBUILD_SHARED_LIBS- 编译动态库 - On - -DBUILD_SHARED_AND_STATIC_LIBS- 编译动态库和静态库 - Off - -DCMAKE_INSTALL_PREFIX- 设置安装路径前缀 - -DENABLE_LOCALES- 开启使用localeconv方法 - On - -DCJSON_OVERRIDE_BUILD_SHARED_LIBS- 使用 - -DCJSON_BUILD_SHARED_LIBS覆盖- BUILD_SHARED_LIBS的值
- 在代码中引入头文件 - #include <cjson/cJSON.h>
 
2 cJSON数据结构
- cJSON使用 - cJSON结构体表示JSON数据- typedef struct cJSON
 {
 /* next和prev允许你遍历array/object链,或者使用GetArraySize/GetArrayItem/GetObjectItem方法 */
 struct cJSON *next;
 struct cJSON *prev;
 /* array/object会拥有child指针,指向它包含的一连串元素 */
 struct cJSON *child; /* 类型 */
 int type; /* 如果type为cJSON_String或cJSON_Raw,使用它保存string值 */
 char *valuestring;
 /* 将值写入valueint已过时,使用cJSON_SetNumberValue代替 */
 int valueint;
 /* 如果type为cJSON_Number,使用它保存number值 */
 double valuedouble;
 /* 如果该节点是array或者object的子元素,则使用它保存名称字符串 */
 char *string;
 } cJSON;
 
- type取值- 取值 - 含义 - 备注 - 检查 - cJSON_Invalid- 非法 - 不包含任何值 - cJSON_IsInvalid- cJSON_False- false- cJSON_IsFalse/- cJSON_IsBool- cJSON_True- true- cJSON_IsTrue/- cJSON_IsBool- cJSON_NULL- null- cJSON_IsNull- cJSON_Number- 数字 - 值将以 - double类型保存在- valuedouble中,同时也保存在- valueint中,如果超出整形范围,则- valueint值为- INT_MAX或者- INT_MIN- cJSON_IsNumber- cJSON_String- 字符串 - 以 - '\0'结尾的形式保存在- valuestring中- cJSON_IsString- cJSON_Array- 数组 - child指针指向数组中各个元素,各元素通过- next/- prev指针串在一起形成链表- cJSON_IsArray- cJSON_Object- 对象 - 同数组保存形式相同,只不过对象中的各个元素会将它们的key值存储在 - string中- cJSON_IsObject- cJSON_Raw- 任意JSON类型 - 以 - '\0'结尾的形式保存在- valuestring中,使用cJSON解析时不会生成这个类型,并且cJSON不会校验JSON的合法性- cJSON_IsRaw- cJSON_IsReference- 引用 - child指向的元素或者- valuestring不被当前节点拥有,当使用- cJSON_Delete时,只会释放当前节点,而不会释放它的- child和- valuestring- cJSON_StringIsConst- 常量字符串 - string指向一个常量字符串,当使用- cJSON_Delete时,将不会释放- string
3 创建cJSON数据
对于每种type,都有一个与之对应的cJSON_Create...方法用于创建该类型的节点,所有方法都会创建一个cJSON结构体,可以使用cJSON_Delete释放它
注意:
- 不能使用cJSON_Delete释放array或object当中的元素,当array或者object被释放时,其中的元素也会自动释放
- 可以使用cJSON_SetValueString改变cJSON_String节点的valuestring值,而不需要手动释放之前的valuestring
3.1 基本类型
| 类型 | 创建方法 | 说明 | 
|---|---|---|
| null | cJSON_CreateNull | |
| boolean | cJSON_CreateTrue/cJSON_CreateFalse/cJSON_CreateBool | |
| number | cJSON_CreateNumber | 将同时设置 valuedouble和valueint,如果数字的值超过整形范围,则valueint将被设为INT_MAX或INT_MIN | 
| string | cJSON_CreateString/cJSON_CreateStringReference | cJSON_CreateString会拷贝字符串,而cJSON_CreateStringReference直接指向设置的字符串 | 
3.2 数组
3.2.1 创建数组
- cJSON_CreateArray:创建一个空数组
- cJSON_CreateArrayReference:创建一个数组,但是它里面的所有元素都不属于它自己,所以不能使用- cJSON_Delete删除它里面的内容
3.2.2 向数组中添加元素
- cJSON_AddItemToArray:在数组尾端添加元素
- cJSON_AddItemReferenceToArray:将另一个元素的引用添加进数组
- cJSON_InsertItemInArray:在指定索引处插入元素
3.2.3 获取数组中的元素
- cJSON_GetArrayItem:根据索引获取元素
- cJSON_DetachItemFromArray:根据索引获取数组中的元素,并将其从数组中分离,以便后续能够继续使用
3.2.4 删除数组中的元素
- cJSON_DeleteItemFromArray:根据索引删除数组中的元素
3.2.5 替换数组中的元素
- cJSON_ReplaceItemInArray:根据索引替换元素
- cJSON_ReplaceItemViaPointer:根据指针替换元素,失败返回0
3.2.6 获取数组的大小
- cJSON_GetArraySize:获取数组的大小
3.2.7 迭代数组中的元素
- cJSON_ArrayForEach:在\(O(n)\)的时间内迭代数组中的元素
3.3 对象
3.3.1 创建对象
- cJSON_CreateObject:创建一个空对象
- cJSON_CreateObjectReference:创建一个对象,但是它里面的所有元素都不属于它自己,所以不能使用- cJSON_Delete删除它里面的内容
3.3.2 向对象中添加元素
- cJSON_AddItemToObject:向对象中添加一个元素
- cJSON_AddItemToObjectCS:向对象中添加一个名称(对象的key,即- cJSON结构体中的- string)为常量或者引用的元素
- cJSON_AddItemReferenceToObject:将另一个元素的引用添加进对象
3.3.3 获取对象中的元素
- cJSON_GetObjectItemCaseSensitive:获取对象中的元素
- cJSON_DetachItemFromObjectCaseSensitive:分离并获取对象中的元素
3.3.4 删除对象中的元素
- cJSON_DeleteItemFromObjectCaseSensitive:删除对象中的元素
3.3.5 替换对象中的元素
- cJSON_ReplaceItemInObjectCaseSensitive:根据key替换对象中的元素
- cJSON_ReplaceItemViaPointer:根据指针替换对象中的元素,失败返回0
3.3.6 获取对象的大小
- cJSON_GetArraySize:获取对象的大小
3.3.7 迭代对象中的元素
- cJSON_ArrayForEach:迭代对象中的元素
3.3.8 快速创建并添加元素到对象
cJSON提供了快速创建并添加到对象的方法,这些方法返回指向新创建元素的指针,如果失败,则返回NULL
- cJSON_AddNullToObject
- cJSON_AddTrueToObject
- cJSON_AddFalseToObject
- cJSON_AddBoolToObject
- cJSON_AddNumberToObject
- cJSON_AddStringToObject
- cJSON_AddRawToObject
- cJSON_AddObjectToObject
- cJSON_AddArrayToObject
4 cJSON解析与输出JSON
4.1 解析JSON
cJSON提供的解析函数的返回值需要手动调用cJSON_Delete释放
- cJSON_Parse:解析以- '\0'结尾的JSON字符串- cJSON * cJSON_Parse(const char *value);
 
- cJSON_ParseWithLength:解析指定长度的JSON字符串(可以不以- '\0'结尾)- cJSON * cJSON_ParseWithLength(const char *value, size_t buffer_length);
 
- cJSON_ParseWithOpts- cJSON * cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
 - return_parse_end:返回指向输入字符串中JSON的结束位置,或解析出错的位置
- require_null_terminated:是否禁止输入字符串中的JSON后面还包含有数据
 
- cJSON_ParseWithLengthOpts- cJSON * cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
 
4.2 输出JSON
cJSON提供的输出函数的返回值需要手动调用free释放
- cJSON_Print:输出经过空白字符格式化后的JSON- char * cJSON_Print(const cJSON *item);
 
- cJSON_PrintUnformatted:输出没有经过空白字符格式化后的JSON- char * cJSON_PrintUnformatted(const cJSON *item);
 
- cJSON_PrintBuffered:输出JSON到指定大小的buffer- char * cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
 - prebuffer:指定输出buffer的初始大小
- fmt:是否使用空白字符进行格式化
 
- cJSON_PrintPreallocated:输出JSON到静态buffer,从而避免动态分配内存,当buffer大小不够时,调用失败,返回0,成功时返回1- cJSON_bool cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
 - 注意:至少提供5字节大小的buffer 
5 cJSON使用示例
{
    "name": "Awesome 4K",
    "resolutions": [
        {
            "width": 1280,
            "height": 720
        },
        {
            "width": 1920,
            "height": 1080
        },
        {
            "width": 3840,
            "height": 2160
        }
    ]
}
5.1 打印输出JSON
5.1.1 方法1
//create a monitor with a list of supported resolutions
//NOTE: Returns a heap allocated string, you are required to free it after use.
char *create_monitor(void)
{
    const unsigned int resolution_numbers[3][2] = {
        {1280, 720},
        {1920, 1080},
        {3840, 2160}
    };
    char *string = NULL;
    cJSON *name = NULL;
    cJSON *resolutions = NULL;
    cJSON *resolution = NULL;
    cJSON *width = NULL;
    cJSON *height = NULL;
    size_t index = 0;
    cJSON *monitor = cJSON_CreateObject();
    if (monitor == NULL)
    {
        goto end;
    }
    name = cJSON_CreateString("Awesome 4K");
    if (name == NULL)
    {
        goto end;
    }
    /* after creation was successful, immediately add it to the monitor,
     * thereby transferring ownership of the pointer to it */
    cJSON_AddItemToObject(monitor, "name", name);
    resolutions = cJSON_CreateArray();
    if (resolutions == NULL)
    {
        goto end;
    }
    cJSON_AddItemToObject(monitor, "resolutions", resolutions);
    for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)
    {
        resolution = cJSON_CreateObject();
        if (resolution == NULL)
        {
            goto end;
        }
        cJSON_AddItemToArray(resolutions, resolution);
        width = cJSON_CreateNumber(resolution_numbers[index][0]);
        if (width == NULL)
        {
            goto end;
        }
        cJSON_AddItemToObject(resolution, "width", width);
        height = cJSON_CreateNumber(resolution_numbers[index][1]);
        if (height == NULL)
        {
            goto end;
        }
        cJSON_AddItemToObject(resolution, "height", height);
    }
    string = cJSON_Print(monitor);
    if (string == NULL)
    {
        fprintf(stderr, "Failed to print monitor.\n");
    }
end:
    cJSON_Delete(monitor);
    return string;
5.1.2 方法2
使用cJSON_Add...ToObject快捷创建和添加元素
//NOTE: Returns a heap allocated string, you are required to free it after use.
char *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 *monitor = cJSON_CreateObject();
    if (cJSON_AddStringToObject(monitor, "name", "Awesome 4K") == NULL)
    {
        goto end;
    }
    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();
        if (cJSON_AddNumberToObject(resolution, "width", resolution_numbers[index][0]) == NULL)
        {
            goto end;
        }
        if (cJSON_AddNumberToObject(resolution, "height", resolution_numbers[index][1]) == NULL)
        {
            goto end;
        }
        cJSON_AddItemToArray(resolutions, resolution);
    }
    string = cJSON_Print(monitor);
    if (string == NULL)
    {
        fprintf(stderr, "Failed to print monitor.\n");
    }
end:
    cJSON_Delete(monitor);
    return string;
}
5.2 解析JSON
/* return 1 if the monitor supports full hd, 0 otherwise */
int supports_full_hd(const char * const monitor)
{
    const cJSON *resolution = NULL;
    const cJSON *resolutions = NULL;
    const cJSON *name = NULL;
    int status = 0;
    cJSON *monitor_json = cJSON_Parse(monitor);
    if (monitor_json == NULL)
    {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            fprintf(stderr, "Error before: %s\n", error_ptr);
        }
        status = 0;
        goto end;
    }
    name = cJSON_GetObjectItemCaseSensitive(monitor_json, "name");
    if (cJSON_IsString(name) && (name->valuestring != NULL))
    {
        printf("Checking monitor \"%s\"\n", name->valuestring);
    }
    resolutions = cJSON_GetObjectItemCaseSensitive(monitor_json, "resolutions");
    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->valuedouble == 1920) && (height->valuedouble == 1080))
        {
            status = 1;
            goto end;
        }
    }
end:
    cJSON_Delete(monitor_json);
    return status;
}
cJSON的使用的更多相关文章
- 在不知道json格式的情况下如何使用cjson进行解析
		假设我们有一个json字符串,但是我们不知道这个json的组织方式,那么如何进行解析呢,下面就给一个小例子. 1.我们的json串如下: { "aStr": "aaaaa ... 
- 使用cjson进行对象的嵌套封装
		共分两个部分,1)创建json.2)解析json 1)创建嵌套json的代码 char * makeJson() { cJSON * pRoot = NULL; cJSON * pSub_1 = NU ... 
- mac 下安装 lua5.3 + cjson
		1.lua 5.3的安装 直接去官网下载 http://www.lua.org/ftp/lua-5.3.3.tar.gz make macosx sudo make install 2.CSJON 编 ... 
- cJSON:  一个用c写的一个简单好用的JSON解析器
		转自:http://blog.csdn.net/chenzhongjing/article/details/9188347 下载地址: http://sourceforge.net/projects/ ... 
- 使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解
		本文用代码简单介绍cjson的使用方法,1)创建json,从json中获取数据.2)创建json数组和解析json数组 1. 创建json,从json中获取数据 #include <stdio. ... 
- cJSON应用举例
		//在网上查了不少cJSON,结果只找到c语言字符串转换到JSON的实例,想转回来结果没有实例.自己琢磨了一个下午才敢下手.下面把转来转去的代码贴上. //百度网盘的 CJSON 实例源码 地址 ht ... 
- JSON格式解析和libjson使用简介(关于cjson的使用示例)
		JSON格式解析和libjson使用简介 在阅读本文之前,请先阅读下<Rss Reader实例开发之系统设计>一文. Rss Reader实例开发中,进行网络数据交换时主要使用到了两种数据 ... 
- Lua利用cjson读写json示例分享
		本文结合本人的实际使用经验和代码示例,介绍如何在Lua中对json进行encode和decode,需要的朋友可以参考下 我这里采用的是Lua CJson库,是一个高性能的JSON解析器和编码器,其性能 ... 
- cJSON学习笔记
		1.JSON格式简述 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写,同时也易于机器解析和生成.它基于JavaScript(Standa ... 
- cJSON 使用笔记
		缘 起 最近在stm32f103上做一个智能家居的项目,其中选择的实时操作系统是 rt_thread OS v1.2.2稳定版本,其中涉及到C和java(android)端数据的交换问题,经 ... 
随机推荐
- [C#] (原创)一步一步教你自定义控件——04,ProgressBar(进度条)
			一.前言 技术没有先进与落后,只有合适与不合适. 本篇的自定义控件是:进度条(ProgressBar). 进度条的实现方式多种多样,主流的方式有:使用多张图片去实现.使用1个或2个Panel放到Use ... 
- Apache Kylin远程代码执行漏洞复现(CVE-2020-1956)
			Apache Kylin远程代码执行(CVE-2020-1956) 简介 Apache Kylin 是美国 Apache 软件基金会的一款开源的分布式分析型数据仓库.该产品主要提供 Hadoop/Sp ... 
- yum安装出现被锁定的报错
			问题:在使用#yum install XXX 命令的时候,出现yum.pid 已被锁定的提示,无法进行yum 安装 解决: 使用# rm -f /var/run/yum.pid 命令删除该进程即可 
- dat.GUI 打造可视化工具(一)
			前言 有时候学习api其实我们可以从源码的角度学习,因为有时候很多文档写的太不清楚了,自己都是慢慢去试,去猜,去实现其实也是挺浪费时间的,面对未知的一脸蒙蔽,偶尔烦躁,其实需要的是自己静下心来慢慢研究 ... 
- simulink产生周期矩形波和8421码
			初次入门simulink,由于学习了数字逻辑,试图进行仿真,首先需要的就是8421码,但是没找到simulink里面相关模块,如果各位知道怎么弄可以评论告诉我分享分享哈哈 我用的是matlab2016 ... 
- I am coming back
			时隔两年,我回来了,回到这个我梦开始的地方,带着一个新的身份--研究生! 
- efcore 学习
			新开一个博客来写一下ef core的学习过程 这个博客内容会跟着官网走 具体可见官网https://docs.microsoft.com/zh-cn/ef/core/get-started/?tabs ... 
- 转载:WIFI无线协议802.11a/b/g/n/ac的演变以及区别
			WIFI无线协议802.11a/b/g/n/ac的演变以及区别 版权声明:版权所有,转载须注明出处. https://blog.csdn.net/Brouce__Lee/article/details ... 
- VMware虚拟机 - 解决 Vmware 启动虚拟机报:该虚拟机似乎正在使用中。 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。否则,请按“取消(C)”按钮以防损坏的问题
			问题背景 当虚拟机仍然在运行时,直接关闭电脑,下次重开电脑并想重新启动虚拟机时报了下图问题 解决方案 进入虚拟机所在目录,把 .lck 后缀的文件都删完 Vmware 重新启动虚拟机 成功!! 
- drop_cache-sar
			查线上问题: 1.cpu idle 为0 ,I/O高, pidstat 发现进程io 不高,那就是cache mem引起系统io高了 没有vmstat,只能使用sar工具了,使用sar -r 查看 ... 
