You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C程序中整合curl与jq解析JSON,无需管道调用?

问题描述

我用C语言结合curl库写了一段HTTP请求代码:

#include <curl/curl.h>
#include <stdio.h>
int main(){
    CURL *ch;
    CURLcode res;
    ch = curl_easy_init();
    curl_easy_setopt(ch, CURLOPT_URL, "https://jsonplaceholder.typicode.com/todos/2");
    res = curl_easy_perform(ch);
    curl_easy_cleanup(ch);
}

编译运行后能正常把返回的JSON输出到命令行:

$./mycurl
{
  "userId": 1,
  "id": 2,
  "title": "quis ut nam facilis et officia qui",
  "completed": false
}

但我不想用./mycurl | jq这种管道方式解析JSON,想把curl请求和JSON解析整合到同一个C文件里,编译成单一可执行文件,该怎么做?

实现方案

你可以集成轻量级C语言JSON解析库(比如cJSON),让curl把响应数据写入内存缓冲区,再直接用JSON库解析缓冲区内容,无需依赖外部jq工具。具体步骤如下:

1. 准备cJSON库

cJSON是单文件实现的JSON解析库,只需将cJSON.c和cJSON.h下载到项目目录即可,无需系统级安装,方便编译成单一可执行文件。

2. 修改代码整合curl与JSON解析

修改后的代码会捕获curl的响应数据,再用cJSON解析并提取所需字段:

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

// curl回调函数:将响应数据写入内存缓冲区
size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    char **mem = (char **)userp;
    
    *mem = realloc(*mem, realsize + 1);
    if (*mem == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return 0;
    }
    
    memcpy(*mem, contents, realsize);
    (*mem)[realsize] = '\0';
    return realsize;
}

int main() {
    CURL *ch;
    CURLcode res;
    char *response = NULL; // 存储curl获取的响应数据

    ch = curl_easy_init();
    if (ch) {
        // 设置请求URL
        curl_easy_setopt(ch, CURLOPT_URL, "https://jsonplaceholder.typicode.com/todos/2");
        // 绑定回调函数,将响应写入内存缓冲区
        curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(ch, CURLOPT_WRITEDATA, &response);

        // 执行HTTP请求
        res = curl_easy_perform(ch);
        if (res != CURLE_OK) {
            fprintf(stderr, "curl请求失败: %s\n", curl_easy_strerror(res));
            curl_easy_cleanup(ch);
            return 1;
        }

        // 解析JSON数据
        cJSON *json = cJSON_Parse(response);
        if (json == NULL) {
            fprintf(stderr, "JSON解析失败\n");
            curl_easy_cleanup(ch);
            free(response);
            return 1;
        }

        // 提取并输出指定字段(示例:userId、title、completed)
        cJSON *userId = cJSON_GetObjectItemCaseSensitive(json, "userId");
        cJSON *title = cJSON_GetObjectItemCaseSensitive(json, "title");
        cJSON *completed = cJSON_GetObjectItemCaseSensitive(json, "completed");

        if (cJSON_IsNumber(userId) && cJSON_IsString(title) && cJSON_IsBool(completed)) {
            printf("用户ID: %d\n", userId->valueint);
            printf("任务标题: %s\n", title->valuestring);
            printf("是否完成: %s\n", completed->valueint ? "是" : "否");
        }

        // 释放所有资源
        cJSON_Delete(json);
        curl_easy_cleanup(ch);
        free(response);
    }
    return 0;
}

3. 编译命令

将cJSON.c、cJSON.h与你的代码文件(比如mycurl.c)放在同一目录,执行以下编译命令:

gcc mycurl.c cJSON.c -o mycurl -lcurl

4. 运行效果

编译完成后运行./mycurl,会直接输出解析后的结构化内容:

$./mycurl
用户ID: 1
任务标题: quis ut nam facilis et officia qui
是否完成: 否

内容的提问来源于stack exchange,提问作者bungee1980

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:12:48