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

当我们需要获取某个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 2023年5月23日
    00
  • C语言 详细讲解逻辑运算符的使用

    C语言 详细讲解逻辑运算符的使用 在C语言中,逻辑运算符用来比较两个条件语句的关系,并返回True或False。 C语言中的逻辑运算符有三种,分别是 &&(逻辑与)、||(逻辑或)和!(逻辑非)。 逻辑与(&&) 逻辑与用于判断两个条件语句是否同时为真,如果两个条件语句都为真,则返回True,否则返回False。 逻辑与的使用…

    C 2023年5月23日
    00
  • C++如何将二叉搜索树转换成双向循环链表(双指针或数组)

    将二叉搜索树转换成双向循环链表是一道比较经典的算法题,本文将对该算法进行完整讲解。 算法思路 我们可以将该问题划分成多个子问题:- 将左子树转换为双向循环链表,并返回链表头和链表尾;- 将右子树转换为双向循环链表,并返回链表头和链表尾;- 将当前节点插入左子树的链表尾,将左子树链表尾连接至当前节点;- 将当前节点插入右子树的链表头,将右子树链表头连接至当前节…

    C 2023年5月23日
    00
  • Java异常处理中同时有finally和return语句的执行问题

    在Java中,异常处理是很常见的编程技巧。然而,当我们的代码中存在finally块和return语句时,代码的执行顺序可能会有一些麻烦。本攻略将会详细解释在Java异常处理中同时有finally和return语句的执行问题。 finally块和return语句的执行顺序 在Java中,当我们的代码发生异常时,代码将进入异常处理程序来处理这些异常。异常处理程序…

    C 2023年5月23日
    00
  • Python时间序列处理之ARIMA模型的使用讲解

    Python时间序列处理之ARIMA模型的使用讲解 本文主要介绍如何使用Python进行时间序列的ARIMA模型处理。ARIMA模型是一种常用的时间序列分析方法,可用于对未来时间序列的预测。本文将详细讲解ARIMA模型的原理和应用,以及如何使用Python完成ARIMA模型的建模和预测。 1. ARIMA模型简介 1.1 模型原理 ARIMA模型是基于时间序…

    C 2023年5月22日
    00
  • Ajax和Comet技术总结

    Ajax和Comet技术总结 Ajax是Asynchronous JavaScript and XML(异步JavaScript和XML)的缩写。它是一种利用JavaScript和XML在Web服务器上异步传输数据的技术。它可以在不重新加载整个网页的情况下,更新某个特定部分的内容。Ajax能够在不干扰客户端的情况下,优化Web应用的性能。 Ajax的优点 网…

    C 2023年5月23日
    00
  • Java EE项目中的异常处理总结(一篇不得不看的文章)

    以下是我对《Java EE项目中的异常处理总结(一篇不得不看的文章)》这篇文章的完整攻略: 文章概述 文章主要分为四个部分:异常处理的基本概念、Java中的异常处理机制、Java EE项目中的异常处理、异常处理的最佳实践等。其中,第一个部分主要介绍了异常处理的基本概念,包括异常的定义、分类、抛出和捕获等。第二个部分则详细讲解了Java中的异常处理机制,包括t…

    C 2023年5月23日
    00
  • C语言指向指向常量的常量指针的指针

    “C语言指向指向常量的常量指针的指针”(const pointer to const pointer)是一个比较复杂的概念,它在C语言中用于处理指针的嵌套问题,即通过一个指针的指针来访问一个变量。下面来详细讲解它的用法及示例: 概述 在C语言中,指针是一个存储内存地址的变量,而指向指针的指针就是一个存储指针的内存地址的变量。而指向常量的常量指针则是一个不能够…

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