C++调用curl请求API解析JSON时抛出std::length_error异常求解
异常原因
- 你尝试写文件再读取解析的代码存在两处基础错误:
- 用
ifstream >> line读取文件内容时,该运算符会在遇到空格、换行、制表符等空白字符时停止读取,而接口返回的JSON里包含空格(比如"createdAt":"2021-09-10 12:12:46"中的空格),导致读出来的line只是JSON的前半部分,内容不完整。 - Windows路径中的反斜杠需要转义,你代码里写的单反斜杠会被识别为转义字符,导致文件打开失败,最终
line为空。
畸形或空的JSON内容传入jsoncpp解析时,就会触发std::length_error。
- 用
- 完整版代码的潜在问题:
- 没有判断
curl_easy_perform的执行结果,若网络请求失败(比如断网、域名解析失败),httpData可能为空或者包含无意义数据,直接解析会出错。 - 接口返回的内容可能隐含BOM头、不可见控制字符、或者非法的空字符
\0,导致jsoncpp计算待解析内容长度时溢出合法范围,抛出长度错误。 result_json函数存在分支未返回值的问题:当HTTP状态码非200、或者JSON解析失败时,函数没有返回任何string值,会触发未定义行为,也可能间接导致内存操作异常。
- 没有判断
- 若使用的是旧版本的jsoncpp,存在已知的解析边界case时抛
length_error的bug。
解决方法
调试场景(写文件读取解析)修正
替换文件读取逻辑,一次性读取全量内容,同时修正路径转义:
// 路径反斜杠转义 ifstream myfile2("C:\\Users\\ingfr\\source\\repos\\Cheat1\\Debug\\example.txt"); // 一次性读取全部内容,不受空格影响 string line((istreambuf_iterator<char>(myfile2)), istreambuf_iterator<char>());
完整版代码优化
- 增加curl执行结果校验,避免请求失败仍尝试解析空数据:
CURLcode res = curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); curl_easy_cleanup(curl); // 先判断curl请求是否成功,再判断状态码,再校验httpData是否为空 if (res != CURLE_OK || httpCode != 200 || httpData->empty()) { std::cout << "请求失败: " << curl_easy_strerror(res) << std::endl; return ""; }
- 解析前先过滤待解析内容里的不可见控制字符,避免异常字符干扰:
// 过滤非打印字符和空字符 std::string clean_data; for (char c : *httpData) { if (c >= 32 || c == '\t' || c == '\n' || c == '\r') { clean_data += c; } }
- 替换已废弃的
Json::Reader为稳定性更好的Json::CharReader:
Json::CharReaderBuilder builder; Json::Value jsonData; std::string err; if (Json::parseFromStream(builder, std::istringstream(clean_data), &jsonData, &err)) { // 原有解析成功的业务逻辑 if (jsonData["status"].asString() == "failed") { return jsonData["error"].asString(); } else { return jsonData[type].asString(); } } else { std::cout << "解析失败: " << err << std::endl; return ""; }
- 补全
result_json所有分支的返回值,避免未定义行为。 - 若仍有问题,升级到最新版的jsoncpp。
内容的提问来源于stack exchange,提问作者CrSerials
相关产品推荐
相关产品推荐

