cJSON-使用简单且功能强大的JSON解析库

用C++处理JSON的库有很多,JSONCPP,json-parser,Jansson…太多了

不过我们搞程序开发,不一定需要一个库有多么强大的功能,但是这个库一定要能满足我们的要求,同时,开发起来要简单,最好不要增加我们的开发负担和学习负担。

我在开发menthol语言的JSON模块处理时,发现了一个简单、易用的JSON处理库-CJSON

看它的官方介绍

Welcome to cJSON. cJSON aims to be the dumbest possible parser that
you can get your job done with. It’s a single file of C, and a single
header file.

JSON is described best here: http://www.json.org/ It’s like XML, but
fat-free. You use it to move data around, store things, or just
generally represent your program’s state.

As a library, cJSON exists to take away as much legwork as it can, but
not get in your way. As a point of pragmatism (i.e. ignoring the
truth), I’m going to say that you can use it in one of two modes: Auto
and Manual. Let’s have a quick run-through.

I lifted some JSON from this page: http://www.json.org/fatfree.html
That page inspired me to write cJSON, which is a parser that tries to
share the same philosophy as JSON itself. Simple, dumb, out of the
way.

就像上面说的,它的使用相对很简单,就两个文件cJSON.c,cJSON.h,开发的时候,引入你的项目中一起编译就可以了。

先要了解一下cjson几个基本类型:cJSON_False,cJSON_True,cJSON_NULL,cJSON_Number,cJSON_String,cJSON_Array,cJSON_Object

1.使用Cjson分析json各时时,要首先使用cJSON_Parse,来返回JSON结构

cJSON *json = cJSON_Parse(string);

Cjson结构如下

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;

2.用cJSON_GetObjectItem来获取你要的key所对应的value

cJSON *json = cJSON_Parse(string);
v = cJSON_GetObjectItemCaseSensitive(json, "key");

3.用type属性来判断返回的数据类型,根据不同的数据类型,取不同的值

v->type

如果type是cJSON_Number,则用v->valuedouble来取数值
如果type是cJSON_String,则用v->valuestring来取数值

4.如果是array,需要用cJSON_GetArrayItem(json,index)来获取一个cJSON*类型,然后在用第3步的方式来获取数据

5.cJSON_GetArraySize可以获取到数组的大小

6.解析完成后需要调用cJSON_Delete删除,第一步返回的指针

cJSON_Delete(json)

看一个官方实例

JSON实例

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

Cjson解析程序

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到具体使用实例,可以查看我开发的menthol语言的JSON模块实现