1 安装cJSON

github地址:https://github.com/DaveGamble/cJSON.git

  1. 下载完成后进入cJSON目录,执行下面命令生成Makefile文件

    mkdir build
    cd build
    cmake ..
  2. 执行下面命令安装cJSON库

    make install
    • 默认将头文件安装到/usr/local/include/cjson路径下
    • 默认将链接库安装到/usr/local/lib路径下
  3. 一些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的值
  4. 在代码中引入头文件

    #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时,只会释放当前节点,而不会释放它的childvaluestring
    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 将同时设置valuedoublevalueint,如果数字的值超过整形范围,则valueint将被设为INT_MAXINT_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的使用的更多相关文章

  1. 在不知道json格式的情况下如何使用cjson进行解析

    假设我们有一个json字符串,但是我们不知道这个json的组织方式,那么如何进行解析呢,下面就给一个小例子. 1.我们的json串如下: { "aStr": "aaaaa ...

  2. 使用cjson进行对象的嵌套封装

    共分两个部分,1)创建json.2)解析json 1)创建嵌套json的代码 char * makeJson() { cJSON * pRoot = NULL; cJSON * pSub_1 = NU ...

  3. 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 编 ...

  4. cJSON: 一个用c写的一个简单好用的JSON解析器

    转自:http://blog.csdn.net/chenzhongjing/article/details/9188347 下载地址: http://sourceforge.net/projects/ ...

  5. 使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解

    本文用代码简单介绍cjson的使用方法,1)创建json,从json中获取数据.2)创建json数组和解析json数组 1. 创建json,从json中获取数据 #include <stdio. ...

  6. cJSON应用举例

    //在网上查了不少cJSON,结果只找到c语言字符串转换到JSON的实例,想转回来结果没有实例.自己琢磨了一个下午才敢下手.下面把转来转去的代码贴上. //百度网盘的 CJSON 实例源码 地址 ht ...

  7. JSON格式解析和libjson使用简介(关于cjson的使用示例)

    JSON格式解析和libjson使用简介 在阅读本文之前,请先阅读下<Rss Reader实例开发之系统设计>一文. Rss Reader实例开发中,进行网络数据交换时主要使用到了两种数据 ...

  8. Lua利用cjson读写json示例分享

    本文结合本人的实际使用经验和代码示例,介绍如何在Lua中对json进行encode和decode,需要的朋友可以参考下 我这里采用的是Lua CJson库,是一个高性能的JSON解析器和编码器,其性能 ...

  9. cJSON学习笔记

    1.JSON格式简述 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写,同时也易于机器解析和生成.它基于JavaScript(Standa ...

  10. cJSON 使用笔记

    缘      起 最近在stm32f103上做一个智能家居的项目,其中选择的实时操作系统是 rt_thread OS v1.2.2稳定版本,其中涉及到C和java(android)端数据的交换问题,经 ...

随机推荐

  1. 深入web workers (上)

    前段时间,为了优化某个有点复杂的功能,我采用了shared workers + indexDB,构建了一个高性能的多页面共享的服务.由于是第一次真正意义上的运用workers,比以前单纯的学习有更多体 ...

  2. dict和list

    一.字典(Dictionary) 1.什么是 dict(字典) 上一章节,我们学习了列表(List) 和 元组(tuple) 来表示有序集合. 而我们在讲列表(list)的时候,我们用了列表(list ...

  3. ERP的主数据的操作与设计--开源软件诞生25

    赤龙ERP主数据管理讲解--第25篇 用日志记录"开源软件"的诞生 [进入地址 点亮星星]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/redr ...

  4. pc端兼容IE9及以上版本

    最近业务部门反映我们商城的兼容性不是很好,尤其是在IE浏览器上,经过调研,我们决定对IE9及以上版本的IE内核浏览器进行主流程测试,发现有哪些功能在IE9上不兼容 一.CSS兼容性 如下图所示 使用了 ...

  5. Spider_基础总结7_爬虫基本模板(3个类)

    # 第四章内容--处理不同的网站布局: # 我们想在功能类似的网站上抓取类似内容时,往往这些网站的内容可能布局不一样(相同内容的标签可能不同),由于通常我们爬取的网站数量有限, # 我们没有必要去开发 ...

  6. 2012年游戏软件开发独立本科段01B0815自考科目

    01B0815自考科目 课程代码[学分] 课程名称 03708[02] 中国近现代史纲要 03709[04] 马克主义基本原理概论 03684[10] 综合英语(四) 01042[05] 应用数学 0 ...

  7. Spring Security 实战干货:OAuth2授权回调的处理机制

    1. 前言 上一文着重讲了当用户发起第三方授权请求是如何初始化OAuth2AuthorizationRequest授权请求对象以及如何通过过滤器进行转发到第三方的.今天我们接着这个流程往下走,来看看服 ...

  8. 初识redis协议

    有关redis协议信息(https://redis.io/topics/protocol) 搭建环境 //jedis连接客户端 public class RedisClient { public st ...

  9. linux中使用head,tail,grep, sed,awk三种方法显示文档中间若干行(指定任意行)

    需要显示文本中间20-25行. 创建一个30行的文档,命名为30.txt并显示在屏幕 [root@v2-ui data]# seq 30 > 30.txt && cat 30.t ...

  10. [web安全原理分析]-XEE漏洞入门

    前言 1 前言 XXE漏洞 XXE漏洞全称(XML External Entity Injection)即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致 ...