cJSON基本知识

最近在物联网项目开发中需要使用到cJSON处理字符串,现就相关详情记录下来方便大家参考以及我以后再次复习,谢谢

cJSON

cJSON是一款以C语言编写的超轻量级的JSON字符串的分析器。

JSON

JSON在这个网站有详细的描述:http://www.json.org/,如需要深入的了解JSON,可以前往进行深入的了解。
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/也对JSON有详细的介绍。

#cJSON使用
有一下几种方法可以使用cJSON:
1.直接copy源文件
由于整个有用的源文件就只有一个c源文件和一个头文件,只需要将cJSON.h 和 cJSON.c复制到你的项目中即可。
2.借助CMake
借助 CMake,cJSON 支持完整的构建系统且支持高于或等于2.8.5版本的CMake。通过这种方式,您可以获得最多的特性和功能。

##cJSON数据结构

/* The cJSON structure: */
typedef struct cJSON {
    struct cJSON *next;
    struct cJSON *prev;
    struct cJSON *child;
    int type;
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    double valuedouble;
    char *string;
} cJSON;

上述结构体中的“type”项表示JSON数据的数据类型。
该字段是以位为标志进行存储的,主要有以下类型:
cJSON_Invalid:代表该数据不包含任何数据;
cJSON_False:代表该数值为false值;
cJSON_True:代表该数值为True值;
cJSON_NULL:代表该数据为NULL;
cJSON_Number:代表该数值为数据型,包括整形和浮点数。
cJSON_String:代表该数值为字符串;
cJSON_Array:代表该数值为数组;
cJSON_Object:代表该数值为对象类型;
cJSON_Raw:代表该数值是以0结尾的数组;
cJSON_IsReference:
cJSON_StringIsConst:

以上每个数据类型都可以通过一个函数cJSON_Create…来进行创建,并通过cJSON_Delete函数删除。
注意:使用cJSON_Create…创建数据结构变量之后一定使用cJSON_Delete删除,以避免内存泄露。

解析cJSON

对于zero结束的JSON 字符串,可以使用函数cJSON_Parse来进行分析。

cJSON *json = cJSON_Parse(string);

对于给的JSON字符串,可以使用函数cJSON_ParseWithLength来进行分析。

cJSON *json = cJSON_ParseWithLength(string, buffer_length);

cJSON默认使用的是内存分配器是malloc和free,但是可以在cJSON_InitHooks里面修改。

如果发生错误,可以使用“cJSON_GetErrorPtr”访问指向输入字符串中错误位置的指针。请注意,尽管这可能会在多线程方案中产生争用条件,但在这种情况下,最好将“cJSON_ParseWithOpts”与“return_parse_end”一起使用。默认情况下,输入字符串中解析的 JSON 后面的字符不会被视为错误。
如果需要更多选项,请使用函数cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
“return_parse_end”返回指向输入字符串中 JSON 末尾的指针或发生错误的位置(从而以线程安全的方式替换“cJSON_GetErrorPtr”)。“require_null_terminated”,如果设置为“1”,则当输入字符串包含 JSON 之后的数据时,将产生错误。
如果需要更多提供缓冲区长度的选项,请使用cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)

打印JSON

可以使用cJSON_Print来打印JSON数据。

char *string = cJSON_Print(json);

cJSON_Print将使用空格进行打印以进行格式化。
如果要在不格式化的情况下打印,请使用cJSON_PrintUnformatted
如果您对生成的字符串有多大有一个粗略的了解,则可以使用cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)fmt是一个布尔值,用于打开和关闭空格格式设置。cJSON_Print当前使用 256 字节作为其第一个缓冲区大小。一旦打印空间不足,就会分配一个新的缓冲区,并在继续打印之前复制旧的缓冲区。
通过使用cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format),可以完全避免这些动态缓冲区分配。它需要一个缓冲区来指向要打印的指针及其长度。如果达到长度,打印将失败并返回0。如果成功,则返回1。请注意,您应该提供比实际需要多 5 个字节,因为 cJSON 在估计提供的内存是否足够时并非 100% 准确。

示例

我们要构建的示例如下:

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

创建和打印的示例代码如下:

//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;
}

创建和打印示例代码2:

//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;
}

cJSON使用注意事项

1、不支持包含'\0' or \u0000的字符串;
2、只支持UTF-8编码的字符串;
3、只支持ANSI C (or C89, C90);
4、cJSON 不正式支持除 IEEE754 双精度浮点数以外的任何“双精度”实现。它可能仍可与其他实现一起使用,但这些实现的 bug 将被视为无效。
cJSON 支持的浮点文本的最大长度当前为 63 个字符。
5、cJSON 不支持嵌套太深的数组和对象,因为这会导致堆栈溢出。为了防止这种情况,cJSON将深度限制为CJSON_NESTING_LIMIT,默认情况下为1000,但可以在编译时更改。
6、通常,cJSON 不是线程安全的 。但是,在以下情况下它是线程安全的:
6.1 从不使用cJSON_GetErrorPtr(可以改用“cJSON_ParseWithOpts”的“return_parse_end”参数)
6.2 cJSON_InitHooks仅在任何线程中使用 cJSON 之前调用过。
6.3 在对 cJSON 函数的所有调用都返回之前,永远不会调用setlocale
7、cJSON 刚开始创建时,没有遵循 JSON 标准,也没有区分大写和小写字母。如果您希望获得正确、符合标准的行为,则需要使用CaseSensitive功能(如果可用)。
8、cJSON 支持解析和打印包含具有相同名称的多个成员的对象的 JSON数据,但是cJSON_GetObjectItemCaseSensitive将始终仅返回第一个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值