cJSON库的安装与使用

介绍

cJSON 库是C语言中的最常用的 JSON 库。github 地址是 https://github.com/DaveGamble/cJSON 。

安装

环境是 Ubuntu 16.04。需要先安装cmake。
cJSON 库安装步骤如下:

git clone https://github.com/DaveGamble/cJSON.git
cd cJSON/
mkdir build
cd build/
cmake ..
make
make install

执行完上述命令后,cJSON.h 头文件会安装在 /usr/local/include/cjson 目录下。libcjson.so 库文件会安装在 /usr/local/lib 目录下。还需要将/usr/local/lib目录添加到 /etc/ld.so.conf 文件中,然后执行 /sbin/ldconfig,否则程序在运行时会报 error while loading shared libraries: libcjson.so.1: cannot open shared object file: No such file or directory 错误。

使用

还是使用显示器支持的分辨率的例子来说明如何使用 cJSON 库生成和解析JSON如下的格式:

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

使用 cJSON 库时,程序只需包含<cjson/cJSON.h>头文件。而在编译时,需要添加 -lcjson 选项。

生成JSON格式

生成 JSON 对象有两种方式:

  • 一是调用 cJSON_CreateXXX 创建相应类型的值(sJSON结构),然后调用 cJSON_AddItemToObject 将值加入到对象中。
  • 二是直接调用 cJSON_AddXXXToObject 创建并添加值到对象中 。

生成 JSON 数组只有一种方式,就是先调用 cJSON_CreateXXX 创建相应类型的值,然后调用 cJSON_AddItemToArray 将值加入到数组中。

最后都要调用 cJSON_Print 将对象或数组转化成 JSON 格式的字符串,调用 cJSON_Delete 释放对象。

生成 JSON 对象的第一种示例代码如下:

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

/* 转换成 JSON 格式的字符串 */
    string = cJSON_Print(monitor);
    if (string == NULL)
    {
        fprintf(stderr, "Failed to print monitor.\n");
    }

end:
/* 释放对象 */
    cJSON_Delete(monitor);
    return string;
}

生成 JSON 对象的第二种示例代码如下:

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

解析JSON格式

解析 JSON 格式,首先要调用 cJSON_Parse 生成用于解析的 cJSON 结构,然后调用 cJSON_GetObjectItemCaseSensitivecJSON_GetObjectItem 获取对应名字的值,用 cJSON_IsXXX 判断值的类型是否正确,然后用 结构中的 valuestring 或 valuedouble 等成员获取值。实例函数代码如下,这个函数判断显示器是否支持 1920x1080 分辨率:

/* 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 结构 */
    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”的值 */
    name = cJSON_GetObjectItemCaseSensitive(monitor_json, "name");
    if (cJSON_IsString(name) && (name->valuestring != NULL))
    {
        printf("Checking monitor \"%s\".\n", name->valuestring);
    }

/* 获取名为“resolutions“的值,它是一个数组 */
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;
}

main 函数

代码如下:

int main(int argc, char **argv)
{
    char *monitor = create_monitor_with_helpers();
    printf("%s\n", monitor);

    if (supports_full_hd(monitor)) {
        printf("It support full HD.\n");
    } 

    free(monitor);
}

程序运行结果如下:

{
"name":"Awesome 4K",
"resolutions":[{
"width":1280,
"height":720
}, {
"width":1920,
"height":1080
}, {
"width":3840,
"height":2160
}]
}
Checking monitor "Awesome 4K".
It support full HD.
(0)

相关推荐