CJSON如何解析JSON数据?

cJSON解析JSON

CJSON如何解析JSON数据?

一、为何选择cJSON

在处理JSON格式时,如果只是处理简单的协议,可以通过对字符串的操作来进行解析与创建,随着协议逐渐复杂化,经常会遇到一些未考虑周全的地方,需要进一步完善解析方法,此时使用一个比较完善的JSON解析库的需求就提出来了,基于方便引用的考虑,我们希望这个JSON解析库是用C语言实现的,同时为了避免太过复杂的C源码包含关系,最好是一个C文件来实现,通过在网络上的查找,发现cJSON是比较符合要求的,cJSON只有一个C文件和一个头文件,包含到项目源码中非常方便,而且其实现效率非常高。

二、cJSON的核心结构体

cJSON的核心结构体是一个名为cJSON的结构体,理解了这个结构体,基本上对cJSON的使用就有了个基本概念了,该结构体具体定义如下:

typedef struct cJSON {
    struct cJSON* next, *prev;       // 遍历数组或对象链的前向或后向链表指针
    struct cJSON *child;              // 数组或对象的孩子节点
    int type;                        // key的类型
    char *valuestring;               // 字符串值
    int valueint;                    // 整数值
    double valuedouble;              // 浮点数值
    char *string;                    // key的名字
} cJSON;

1、数据存储方式:cJSON是使用链表来存储数据的,其访问方式很像一颗树,每一个节点可以有兄弟节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层,只有节点是对象或数组时才可以有孩子节点。

2、键的类型:type是键(key)的类型,一共有7种取值,分别是:False,True,NULL,Number,String,Array,Object,若是Number类型,则valueint或valuedouble中存储着值,若期望的是int,则访问valueint,若期望的是double,则访问valuedouble,可以得到值,若是String类型的,则valuestring中存储着值,可以访问valuestring得到值。

3、键的名称:string中存放的是这个节点的名字,可理解为key的名称。

三、解析JSON格式

1. 解析一个键值对

一个简单的键值对字符串,要解析的目标如下:

{"firstName":"Brett"}

要进行解析,也就是要分别获取到键与值的内容,我们很容易就能看出键为firstName,值为Brett,可是,使用cJSON怎么解析呢?对于这个简单的例子,只需要调用cJSON的三个接口函数就可以实现解析了,这三个函数的原型如下:

cJSON* cJSON_Parse(const char *value);
cJSON* cJSON_GetObjectItem(cJSON *object, const char *string);
void cJSON_Delete(cJSON *c);

解析过程描述如下:

1、首先调用cJSON_Parse()函数,解析JSON数据包,并按照cJSON结构体的结构序列化整个数据包,使用该函数会通过malloc()函数在内存中开辟一个空间,使用完成需要手动释放。

CJSON如何解析JSON数据?

    cJSON* root = cJSON_Parse(json_string);

2、调用cJSON_GetObjectItem()函数,可从cJSON结构体中查找某个子节点名称(键名称),如果查找成功可把该子节点序列化到cJSON结构体中。

    cJSON* item = cJSON_GetObjectItem(root, "firstName");

3、如果需要使用cJSON结构体中的内容,可通过cJSON结构体中的valueintvaluestring取出有价值的内容(即键的值),本例子中,我们直接访问item->valuestring就获取到"Brett"的内容了。

4、通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。

    cJSON_Delete(root);

这样就完成了一次cJSON接口调用,实现了解析工作,使用起来其实也很简单。

2. 解析一个结构体

我们来个复杂一点的,解析一个结构体,要解析的目标如下:

{
    "person": {
        "firstName": "z",
        "lastName": "jadena",
        "email": "jadena@126.com",
        "age": 8,
        "height": 1.17
    }
}

看起来比一个键值对复杂多了,我们又需要学习新的接口函数了吗?答案是不需要!还是那三个函数就可以了,解析的步骤要复杂一些,下面按解析过程来描述一次:

1、根据JSON串中的对象,我们定义一个相应的结构体如下:

    typedef struct {
        char firstName[32];
        char lastName[32];
        char email[64];
        int age;
        float height;
    } PERSON;

2、还是调用cJSON_Parse()函数,解析JSON数据包。

    cJSON* root = cJSON_Parse(json_string);

3、调用一次cJSON_GetObjectItem()函数,获取到对象person。

CJSON如何解析JSON数据?

    cJSON* object = cJSON_GetObjectItem(root, "person");

4、对我们刚取出来的对象person,多次调用cJSON_GetObjectItem()函数,来获取对象的成员,此时要注意,不同的成员,访问的方法不一样:

    cJSON* item;
    PERSON person;
    item = cJSON_GetObjectItem(object, "firstName");
    memcpy(person.firstName, item->valuestring, strlen(item->valuestring));
    item = cJSON_GetObjectItem(object, "lastName");
    memcpy(person.lastName, item->valuestring, strlen(item->valuestring));
    item = cJSON_GetObjectItem(object, "email");
    memcpy(person.email, item->valuestring, strlen(item->valuestring));
    item = cJSON_GetObjectItem(object, "age");
    person.age = (int)item->valueint;
    item = cJSON_GetObjectItem(object, "height");
    person.height = (float)item->valuedouble;

5、最后别忘了释放内存。

    cJSON_Delete(root);

四、常见问题FAQs

Q1: cJSON如何解析嵌套的JSON对象?

A1: cJSON通过递归的方式解析嵌套的JSON对象,可以使用cJSON_GetObjectItem()函数逐层获取嵌套对象的键值对。

cJSON* parent = cJSON_GetObjectItem(root, "parentKey");
cJSON* child = cJSON_GetObjectItem(parent, "childKey");

Q2: cJSON如何处理数组类型的数据?

A2: cJSON通过链表的方式来处理数组类型的数据,可以使用cJSON_GetArrayItem()函数来获取数组中的元素。

cJSON* array = cJSON_GetObjectItem(root, "arrayKey");
cJSON* element = cJSON_GetArrayItem(array, 0); // 获取数组的第一个元素

Q3: cJSON如何释放已分配的内存?

A3: cJSON提供了cJSON_Delete()函数来释放已分配的内存,在解析完成后,应调用该函数来避免内存泄漏。

cJSON_Delete(root); // 释放根对象及其所有子对象

以上就是关于“cjson解析json”的问题,朋友们可以点击主页了解更多内容,希望可以够帮助大家!

原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1493070.html

本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。

(0)
未希
上一篇 2025-01-16 01:09
下一篇 2023-11-27 14:18

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

产品购买 QQ咨询 微信咨询 SEO优化
分享本页
返回顶部
云产品限时秒杀。精选云产品高防服务器,20M大带宽限量抢购 >>点击进入