C++用nlohmann/JSON解析自定义类型时from_json崩溃
崩溃核心原因
代码崩溃是三个匹配错误共同导致的:
- 类型不匹配:你传入的JSON根节点是数组(用
[]包裹),但from_json逻辑里直接用j.at("poly")按对象取键,数组没有键名,调用at()会直接抛出json::type_error异常,你没有捕获异常就会触发程序崩溃。 - 结构不匹配:你定义的
polyfinding结构体期望JSON是包含poly、Finding两个键的嵌套对象,但你实际的JSON是长度为2的平级数组,第一个元素存多边形数据,第二个存结果字段,完全没有poly这个嵌套键。 - 字段名拼写不匹配:C++代码里定义的结果字段名是
Finding(单数),JSON里写的是Findings(复数),就算结构对齐也会因为找不到键抛异常。
修复方法
二选一即可,推荐优先用方案1,结构更清晰,也符合你一开始的序列化/反序列化函数设计。
方案1:修改JSON文件,匹配现有C++结构体逻辑
把test.json的内容改成和你结构体对应的嵌套对象格式,同时修正字段拼写:
{ "poly": { "all_points_x": [1558, 1551, 1470, 1432, 1555], "all_points_y": [1337, 1478, 1474, 1390, 1340], "name": "polygon" }, "Finding": "Fragment" }
同时给代码加异常捕获和文件打开校验,避免解析失败直接崩溃:
json ReadJSONfile(CString pn) { std::ifstream i(pn); if (!i.is_open()) { throw std::runtime_error("JSON文件打开失败,检查路径是否正确"); } json j; i >> j; return j; } void MyTestRoutine() { try { json j = ReadJSONfile("C:\\test.json"); polyfinding TheData; from_json(j, TheData); // 后续业务逻辑 } catch (const std::exception& e) { // 这里可以打印错误信息定位问题,比如e.what() MessageBoxA(NULL, e.what(), "解析错误", MB_OK); } }
方案2:修改C++解析逻辑,适配现有JSON格式
如果你必须保留当前平级数组的JSON结构,就不需要用原来写的polyfinding全局from_json函数,直接按数组结构解析即可:
void MyTestRoutine() { try { json j = ReadJSONfile("C:\\test.json"); // 先校验JSON格式是否符合预期 if (!j.is_array() || j.size() < 2) { throw std::runtime_error("JSON格式不符合要求,需要长度为2的数组"); } polyfinding TheData; // 数组第一个元素是equupoly类型的多边形数据 j[0].get_to(TheData.poly); // 数组第二个元素取结果字段,注意原JSON里键名是Findings(复数) j[1].at("Findings").get_to(TheData.Finding); // 后续业务逻辑 } catch (const std::exception& e) { MessageBoxA(NULL, e.what(), "解析错误", MB_OK); } }
注意:如果选方案2,你之前写的
polyfinding对应的to_json/from_json全局函数序列化出来的结构和你现有JSON结构不统一,后续如果要写JSON文件会出现格式不一致问题,建议优先调整JSON结构用方案1。
内容的提问来源于stack exchange,提问作者Tullhead
相关产品推荐
相关产品推荐

