IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> cJSON的使用和注意事项 -> 正文阅读

[C++知识库]cJSON的使用和注意事项

目录

1.cJSON源码获取

2.cJSON的使用

2.1 增

2.2 删

2.3 改

2.4 查

3.使用注意事项

4.cJSON源码简要分析


工作差不多一年,有很多次用到cJSON这个开源库,这个库用起来很简单,但是也有些地方需要注意。这里来记录下。

1.cJSON源码获取

cJSON库获取

2.cJSON的使用

将上面所有文件下载下来后,这里只需要关注两个文件:cJSON.c和cJSON.h

下面就来看看这两个文件中的代码如何使用:

2.1 增

相关API:

/* Helper functions for creating and adding items to an object at the same time.
 * They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);

举例:

#include <stdio.h>
#include "cJSON.h"
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

int main(void)
{
    char jsonBuf[] = "{\"name\":\"lhsmd\", \"sex\":\"男\", \"fav\":{\"eat\":\"water\"}}";
    cJSON *cJSONTest = cJSON_Parse(jsonBuf);   /* 记得调用cJSON_Delete释放空间 */
    cJSON *p = cJSON_GetObjectItem(cJSONTest, "name");
    if(cJSON_IsString(p))                   /* 判断key的value是否为string */
    {
        printf("%s\r\n", p->valuestring);   /* 输出 */
    }



    cJSON *p1 = cJSON_AddStringToObject(cJSONTest, "add", "me");
    if(p1 != NULL)
    {
        char *p2 = cJSON_Print(cJSONTest);  /* 按照格式输出json  cJSON_PrintUnformatted表示格式化输出输出是一长串 */
        if(p2 != NULL)
        {
            printf("%s\r\n", p2);
            free(p2);
            p2 = NULL;
        }
    }

    cJSON_Delete(cJSONTest);
    return 0;
}


输出结果:

2.2 删

相关API:

/* Remove/Detach items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);

举例:

#include <stdio.h>
#include "cJSON.h"
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

int main(void)
{
    char jsonBuf[] = "{\"name\":\"lhsmd\", \"sex\":\"男\", \"fav\":{\"eat\":\"water\"}}";
    cJSON *cJSONTest = cJSON_Parse(jsonBuf);   /* 记得调用cJSON_Delete释放空间 */
    cJSON *p = cJSON_GetObjectItem(cJSONTest, "name");
    if(cJSON_IsString(p))                   /* 判断key的value是否为string */
    {
        printf("%s\r\n", p->valuestring);   /* 输出 */
    }

    cJSON_DeleteItemFromObject(cJSONTest, "name");
    char *p3 = cJSON_Print(cJSONTest);  /* 按照格式输出json  cJSON_PrintUnformatted表示格式化输出输出是一长串 */
    if(p3 != NULL)
    {
        printf("%s\r\n", p3);
        free(p3);
        p3 = NULL;
    }
    cJSON_Delete(cJSONTest);
    return 0;
}


输出:

2.3 改

相关API:

/* Update array items. */
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);

举例:

#include <stdio.h>
#include "cJSON.h"
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

int main(void)
{
    char jsonBuf[] = "{\"name\":\"lh\", \"sex\":\"男\", \"fav\":{\"eat\":\"water\"}}";
    cJSON *cJSONTest = cJSON_Parse(jsonBuf);   /* 记得调用cJSON_Delete释放空间 */
    cJSON *p = cJSON_GetObjectItem(cJSONTest, "name");
    if(cJSON_IsString(p))                   /* 判断key的value是否为string */
    {
        printf("%s\r\n", p->valuestring);   /* 输出 */
    }

    cJSON_ReplaceItemInObjectCaseSensitive(cJSONTest, "name", cJSON_CreateString("smd"));
    char *p2 = cJSON_Print(cJSONTest);  /* 按照格式输出json  cJSON_PrintUnformatted表示格式化输出输出是一长串 */
    if(p2 != NULL)
    {
        printf("%s\r\n", p2);
        free(p2);
        p2 = NULL;
    }

    cJSON *json = cJSON_CreateObject();
    if(json != NULL)
    {
        if(cJSON_AddStringToObject(json, "eat" ,"food"))
        {
            if(cJSON_ReplaceItemInObjectCaseSensitive(cJSONTest, "fav", json))
            {
                p2 = cJSON_Print(cJSONTest);  /* 按照格式输出json  cJSON_PrintUnformatted表示格式化输出输出是一长串 */
                if(p2 != NULL)
                {
                    printf("%s\r\n", p2);
                    free(p2);
                    p2 = NULL;
                }
            }
        }
    }
    cJSON_Delete(cJSONTest);
    return 0;
}

输出:

2.4 查

查在使用中是使用最多的了,这里给一个实际用到的例子:

现在有一个WIFI模组,需要获取到了来自云端服务器的数据,这些数据是以json的格式下发的,在WIFI模组本地,开启了一个任务(线程),时刻监控来自云端服务器的数据,接收到数据后,需要在这些json数据中提取你想要的数据。现在你已经知道接收数据的格式以及需要提取value的key,那么简单地你可以这么实现:

(代码暂时找不到了,待后续有时间补上)未完待续~~~~~~~~~~~~~

3.使用注意事项

在使用cJSON的过程,需要注意堆空间的释放,具体需要关注的对象有:

1.cJSON_Print系列,需要使用free或者cJSON_free释放

/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);

2.cJSON_Create系列,使用cJSON_Delete释放


/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);

/* Create a string where valuestring references a string so
 * it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/array that only references it's elements so
 * they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);

/* These utilities create an Array of count items.
 * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);

3.cJSON_Parse,使用cJSON_Delete释放

CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);

4.cJSON源码简要分析

在cJSON源码的cJSON.h中,有一个很重要的结构体:

/* The cJSON structure: */
typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;

    /* The type of the item, as above. */
    int type;

    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    /* The item's number, if type==cJSON_Number */
    double valuedouble;

    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
    char *string;
} cJSON;

这是一个双向循环链表,事实上,从代码分析,在给定json的数据中,每一个键值对都是一个链表里面的一个节点。json数据的增删改查都是通过这个双向链表实现的。

如果有时间,在介绍学习具体的源码。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:18:35  更:2022-03-24 00:19:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:19:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码