C语言libcurl自定义回调返回JSON含多余数字致解析失败问题
问题根源
你遇到的末尾额外数字,是因为libcurl传给回调的data是原始二进制字节流,没有自动添加C字符串必需的终止符\0。直接用printf("%s", data)或json_tokener_parse(data)时,函数会越界读取内存里的随机内容,那些0、1就是这么来的——而libcurl默认回调内部处理了字符串终止逻辑,所以不会出问题。
解决办法
1. 打印数据用fwrite替代printf("%s")
不需要依赖字符串终止符,直接按实际响应长度打印:
static size_t callback(void *data, size_t size, size_t nmemb, void *userp) { size_t real_size = size * nmemb; printf("This is the data:\n"); fwrite(data, 1, real_size, stdout); printf("\n"); // 解析JSON前先给数据加终止符 char *json_str = malloc(real_size + 1); if(json_str) { memcpy(json_str, data, real_size); json_str[real_size] = '\0'; jobj = json_tokener_parse(json_str); free(json_str); } return real_size; }
2. 严谨方案:先收集全部响应再处理
libcurl的回调可能被多次调用(大响应会分片返回),单次回调直接解析JSON也可能出错。可以用userp传递缓冲区,收集完所有数据后统一解析:
// 定义结构体存储响应数据 typedef struct { char *buffer; size_t size; } ResponseData; static size_t callback(void *data, size_t size, size_t nmemb, void *userp) { ResponseData *resp = (ResponseData *)userp; size_t real_size = size * nmemb; // 扩容缓冲区 char *new_buf = realloc(resp->buffer, resp->size + real_size + 1); if(!new_buf) return 0; // 内存分配失败直接返回 resp->buffer = new_buf; memcpy(resp->buffer + resp->size, data, real_size); resp->size += real_size; resp->buffer[resp->size] = '\0'; // 确保字符串终止 return real_size; } // 使用示例 int main() { ResponseData resp = {NULL, 0}; CURL *curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); // 设置其他请求参数... curl_easy_perform(curl); // 请求完成后处理数据 if(resp.buffer) { printf("完整响应:\n%s\n", resp.buffer); jobj = json_tokener_parse(resp.buffer); free(resp.buffer); } curl_easy_cleanup(curl); } }
3. 临时应急:手动复制数据并加终止符(仅适用于小响应)
如果能确定响应体积很小、只会触发一次回调,可以临时复制数据并添加终止符,但不推荐用于大响应场景:
static size_t callback(void *data, size_t size, size_t nmemb, void *userp) { size_t real_size = size * nmemb; char temp[1024]; // 假设响应不超过1023字节 if(real_size < 1023) { memcpy(temp, data, real_size); temp[real_size] = '\0'; printf("This is the data:\n%s\n", temp); jobj = json_tokener_parse(temp); } return real_size; }
内容的提问来源于stack exchange,提问作者Laura
相关产品推荐
相关产品推荐

