使用RapidJSON解析JSON时触发abort() has been called错误求助
解决RapidJSON解析UTF16 JSON时触发"abort() has been called"的问题
这个abort错误其实很好定位,我帮你拆解一下原因和解决办法:
核心问题:JSON字符串带隐藏的UTF-16 BOM
你定义的request字符串开头有个不可见的UTF-16字节顺序标记(U+FEFF)——就是那个你看不到的字符,导致RapidJSON解析失败。RapidJSON默认不会自动跳过BOM,它会把这个字符当成JSON的第一个字符,直接违反JSON语法规则,导致d.Parse(request)执行后,文档处于无效状态。
当你后续尝试访问d[L"result"]时,RapidJSON的调试断言机制会检测到你在操作一个无效的文档,直接触发abort()终止程序。
另外顺便提一句:你原代码里的wcscmp判断逻辑反了——wcscmp返回0表示两个字符串相等,原代码的条件会导致成功时输出"Fail",失败时输出"Success",这个也得修正。
解决办法
这里给你三个可行的方案,按需选择:
1. 手动移除字符串中的BOM
直接把request开头的隐藏BOM删掉,确保JSON从{开始:
wchar_t request[] = L"{\"result\":\"OK\"}";
(注意:这个BOM通常是复制粘贴时带进来的,建议手动输入字符串,或者用能显示不可见字符的文本编辑器(比如VS Code开启"控制字符显示")删除它)
2. 让RapidJSON自动处理BOM
如果你的场景需要兼容带BOM的UTF-16输入,可以在Parse时添加kParseAllowUTF16BOM标志,让库自动识别并跳过BOM:
d.Parse<kParseDefaultFlags | kParseAllowUTF16BOM>(request);
3. 强制添加解析错误检查
不管用哪种方案,都建议在解析后先检查是否成功,避免后续的无效操作:
if (d.HasParseError()) { wcout << L"解析失败,错误码:" << d.GetParseError() << L",偏移位置:" << d.GetErrorOffset() << endl; return 1; }
修正后的完整代码
这里给你整合了所有优化点的代码:
#include <iostream> #include <cstdlib> #include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/encodings.h" #include "rapidjson/stringbuffer.h" using namespace std; using namespace rapidjson; typedef GenericDocument<UTF16<> > WDocument; typedef GenericValue<UTF16<> > WValue; // 移除了BOM的JSON字符串 wchar_t request[] = L"{\"result\":\"OK\"}"; int main() { WDocument d; // 如果需要兼容带BOM的输入,替换成下面这行: // d.Parse<kParseDefaultFlags | kParseAllowUTF16BOM>(request); d.Parse(request); // 先检查解析是否成功 if (d.HasParseError()) { wcout << L"解析失败,错误码:" << d.GetParseError() << endl; system("pause"); return 1; } // 先检查成员存在且是字符串类型,再访问 if (d.HasMember(L"result") && d[L"result"].IsString()) { WValue& v = d[L"result"]; // 修正wcscmp的判断逻辑 if (wcscmp(v.GetString(), L"OK") == 0) { cout << "Success!" << endl; } else { cout << "Fail!" << endl; } } else { cout << "缺少'result'成员或该成员不是字符串类型!" << endl; } system("pause"); return 0; }
内容的提问来源于stack exchange,提问作者Андрій Немченко
相关产品推荐
相关产品推荐

