如何在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
相关产品推荐
相关产品推荐

