C语言利用cJSON解析JSON格式全过程

yizhihongxing

当我们需要获取某个Web API的数据时,一般情况下会返回JSON格式的数据。如何使用C语言来解析这些JSON数据呢?这时候,就可以使用cJSON开源库。

cJSON是一款轻量级、快速的C语言JSON解析器。它使用简单,只需要包含一个头文件"cJSON.h",并将相关代码文件加入到项目中即可。下面将详细讲解cJSON解析JSON格式的全过程。

第一步:安装cJSON

可以通过github下载cJSON代码,然后将cJSON.c和cJSON.h文件加入到项目中即可。

第二步:获取JSON数据

我们需要先获取Web API的数据,这里我们可以使用CURL库来发送网络请求,获取JSON数据,例如:

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>

int main(int argc, char *argv[]) {
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init(); // 初始化CURL
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/api/users");
        res = curl_easy_perform(curl); // 执行请求
        if (res != CURLE_OK) { // 如果请求失败
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        }
        curl_easy_cleanup(curl); // 清理CURL
    }

    return 0;
}

执行上面的代码,可以得到JSON格式的数据。如下所示:

{
    "status": "success",
    "users": [
        {
            "id": 1,
            "name": "John Doe",
            "email": "john.doe@example.com"
        },
        {
            "id": 2,
            "name": "Jane Doe",
            "email": "jane.doe@example.com"
        }
    ]
}

第三步:解析JSON数据

我们已经获得了JSON格式的数据,接下来我们需要将它解析成我们所需要的数据。

首先,我们创建一个cJSON对象(通过调用cJSON_Parse函数),并将JSON格式的数据作为参数传入:

cJSON *root = cJSON_Parse(json_data);

其中,json_data是我们获取到的JSON数据。

然后,就可以通过cJSON提供的接口获取JSON对象的值了。例如,要获取上述JSON中每个用户的名称,可以像这样:

cJSON *users = cJSON_GetObjectItem(root, "users");
if (users) {
    cJSON *user = NULL;
    cJSON_ArrayForEach(user, users) { // 遍历users数组
        cJSON *name = cJSON_GetObjectItem(user, "name");
        printf("username: %s\n", name->valuestring);
    }
}

另外,cJSON还提供了一些方便的宏,比如cJSON_GetArrayItem、cJSON_GetObjectItemCaseSensitive等,用于获取数组项、大小写敏感对象值等。

示例一

下面是一个完整的程序,展示如何使用cJSON解析JSON数据,并打印每个用户的名称:

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include "cJSON.h"

int main(int argc, char *argv[]) {
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init(); // 初始化CURL
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/api/users");
        res = curl_easy_perform(curl); // 执行请求
        if (res == CURLE_OK) { // 如果请求成功
            char *json_data = NULL;
            cJSON *root = NULL;

            curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &json_data);
            if (json_data && strstr(json_data, "application/json")) { // 只解析JSON格式的数据
                curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res);
                if (res == 200) { // 只解析请求成功的响应
                    curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &len); // 获取下载的数据长度
                    json_data = (char *) malloc((len+1) * sizeof(char)); // 分配内存
                    if (json_data) {
                        curl_easy_getinfo(curl, CURLINFO_DATA_OUT, &json_data); // 以字符串形式获取数据
                        json_data[len] = '\0';
                        root = cJSON_Parse(json_data); // 将json_data解析成cJSON对象
                        if (root) {
                            cJSON *users = cJSON_GetObjectItem(root, "users");
                            if (users) {
                                cJSON *user = NULL;
                                cJSON_ArrayForEach(user, users) { // 遍历users数组
                                    cJSON *name = cJSON_GetObjectItem(user, "name");
                                    if (name) {
                                        printf("username: %s\n", name->valuestring);
                                    }
                                }
                            }
                            cJSON_Delete(root); // 删除cJSON对象
                        }
                        free(json_data); // 释放内存
                    }
                }
            }
        }
        curl_easy_cleanup(curl); // 清理CURL
    }

    return 0;
}

示例二

下面是一个更复杂的示例,展示如何从复杂的JSON数据中解析出我们需要的值:

{
    "status": "success",
    "result": {
        "total": 2,
        "data": [
            {
                "id": 1,
                "name": {
                    "first": "John",
                    "last": "Doe"
                },
                "email": "john.doe@example.com",
                "addresses": [
                    {
                        "street": "123 Main Street",
                        "city": "Anytown",
                        "state": "CA",
                        "zip": "12345"
                    },
                    {
                        "street": "456 Maple Street",
                        "city": "Othertown",
                        "state": "NY",
                        "zip": "67890"
                    }
                ]
            },
            {
                "id": 2,
                "name": {
                    "first": "Jane",
                    "last": "Doe"
                },
                "email": "jane.doe@example.com",
                "addresses": [
                    {
                        "street": "789 Elm Street",
                        "city": "Sometown",
                        "state": "FL",
                        "zip": "13579"
                    }
                ]
            }
        ]
    }
}

要获取每个用户的名称和地址,可以像这样:

cJSON *result = cJSON_GetObjectItem(root, "result");
if (result) {
    cJSON *data = cJSON_GetObjectItem(result, "data");
    if (data) {
        cJSON *user = NULL;
        cJSON_ArrayForEach(user, data) { // 遍历data数组
            cJSON *name = cJSON_GetObjectItem(user, "name");
            if (name) {
                cJSON *first = cJSON_GetObjectItem(name, "first");
                cJSON *last = cJSON_GetObjectItem(name, "last");
                printf("username: %s %s\n", first->valuestring, last->valuestring);
            }
            cJSON *addresses = cJSON_GetObjectItem(user, "addresses");
            if (addresses) {
                cJSON *address = NULL;
                cJSON_ArrayForEach(address, addresses) { // 遍历addresses数组
                    cJSON *street = cJSON_GetObjectItem(address, "street");
                    cJSON *city = cJSON_GetObjectItem(address, "city");
                    cJSON *state = cJSON_GetObjectItem(address, "state");
                    cJSON *zip = cJSON_GetObjectItem(address, "zip");
                    printf("%s, %s, %s %s\n", street->valuestring, city->valuestring, state->valuestring, zip->valuestring);
                }
            }
        }
    }
}

最后一步:清理

最后,我们需要在程序结束时清理cJSON对象和其他资源:

cJSON_Delete(root);

这样,我们就可以顺利地完成JSON数据的解析了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言利用cJSON解析JSON格式全过程 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C++面向对象实现万年历的示例代码

    以下是对 C++面向对象实现万年历的示例代码 的详细讲解攻略。 前置知识 在学习本教程前,我们需要掌握以下基础知识: C++的基本语法 C++中的面向对象编程 C++中文件操作的基本操作 C++中的日期和时间处理 示例代码 下面是一个简单的C++面向对象实现万年历的示例代码: #include <iostream> #include <fs…

    C 2023年5月22日
    00
  • jQuery简单验证上传文件大小及类型的方法

    下面就是对于“jQuery简单验证上传文件大小及类型的方法”的详细攻略。 什么是文件验证? 文件上传是Web开发中常用的功能,但是常常需要验证上传文件的大小、类型等信息。通过对文件进行验证,可以避免上传恶意或者不支持的文件类型,也可以限制文件的大小,避免系统资源浪费,提高系统的安全性和稳定性。 如何使用jQuery验证上传文件大小及类型? 在jQuery中,…

    C 2023年5月23日
    00
  • C++中引用的相关知识点小结

    C++中引用是一个非常重要的概念,使用它可以有效地提高代码的可读性和性能。本文将介绍引用的相关知识点,并通过示例说明如何使用引用。 引用的概念和基本语法 引用是一个已经存在的变量的别名,通过这个别名可以访问到这个变量的值。在C++中,通过在变量名前加“&”符号来定义一个引用。例如: int a = 1; int& b = a; 这里的“b”就…

    C 2023年5月22日
    00
  • C语言中实现协程案例

    下面我将为你详细讲解C语言中实现协程的完整攻略。 什么是协程 协程(Coroutines)又被称为协作式多任务处理(Cooperative multitasking),是一种计算机程序组件,协程意味着函数可以在中途停止执行,稍后再从停止的地方恢复执行。协与同步和异步执行的程序单元不同,协程通常是基于更高级和更具抽象性的概念。协程可以被视为子例程的泛化,因为它…

    C 2023年5月22日
    00
  • C语言中的编码小技巧

    当我们使用C语言编写代码时,有一些小技巧可以帮助我们写出更优美、更高效、更易于维护的代码。 1. 使用位运算来进行数值操作 在C语言中,位运算符(&、|、^、~、<<、>>)用于在二进制位级别上进行操作。这些运算符可以非常快速地执行某些数值计算,比如: 判断一个数是否是奇数或偶数:使用&运算符,如果一个数的最后一位是0…

    C 2023年5月23日
    00
  • 让PHP以ROOT权限执行系统命令的方法

    为了让PHP以ROOT权限执行系统命令,我们可以采用以下几种方法: 方法一:利用sudo命令 首先需要确保服务器上已经安装sudo,并且已经配置好了sudoers文件,即在sudoers文件中添加了允许PHP执行特定命令的规则,例如: www-data ALL=(ALL:ALL) NOPASSWD: /usr/bin/command 其中,www-data是…

    C 2023年5月22日
    00
  • C++中基类和派生类之间的转换实例教程

    C++中基类和派生类之间的转换实例教程 什么是基类和派生类呢? 在C++中,基类和派生类是面向对象编程中的两个基本概念。基类通常是一个抽象的概念,它定义了一些通用的特征,在派生类中被继承和扩展。派生类则是从基类派生出来的类,它继承了基类的特性,并在此基础上增加了一些自己的特性。 转换示例 我们来看一个实际的示例,假设现在我们有一个基类People,和一个派生…

    C 2023年5月22日
    00
  • C语言实现数学表达式运算

    C语言实现数学表达式运算 概述 C语言提供了一系列函数库,可以实现数学表达式的运算。本篇攻略将介绍如何使用C语言实现数学表达式的运算的方法。 函数库 在C语言中实现数学表达式计算,可以使用数学函数库<math.h>和字符串处理函数库<string.h>。 <math.h>函数库 该函数库中包括了常见的数学函数,例如四则运算…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部