直接用 nlohmann::json 解析嵌套数组,支持任意深度、无需预定义结构;通过 json::parse() 加载,用连缀访问如 "a"["b"],缺失键用 value() 设默认值,遍历时先 is_object() 判断再取值,避免异常。

用 nlohmann/json 直接读取嵌套数组,别手写解析器
直接上 nlohmann::json —— 它原生支持任意深度的嵌套数组和对象,无需预定义结构,也避免手动递归解析出错。C++ 标准库不带 JSON 支持,自己写解析器容易在边界(如空数组、null 元素、类型混用)上崩溃。
实操建议:
- 用
json::parse()从字符串或文件加载,失败时检查json::parse_error异常里的byte位置,快速定位 malformed 字符 - 嵌套数组访问用连缀
["a"][0]["b"][2]["c"]即可,它返回json&,支持链式调用 - 如果某层可能缺失(比如
data.items[0].meta有时不存在),改用value()提供默认值:j["data"]["items"][0].value("meta", json::object())
遍历嵌套数组时,类型检查比 try-catch 更可靠
常见错误是假设 j["list"][i] 一定是对象,结果遇到 null 或字符串就触发 type_error 异常。与其捕获异常,不如提前用 is_array()、is_object()、is_null() 判断。
示例场景:解析日志数组,每个元素可能是 {"level":"info","msg":"ok"},也可能是 null 或 "skipped":
for (auto& item : j["logs"]) {
if (!item.is_object()) continue; // 跳过 null / string / number
std::string level = item.value("level", "unknown");
std::string msg = item.value("msg", "");
}
性能关键:避免重复解析同一段 JSON 字符串
如果要多次访问 j["response"]["data"][i]["items"],不要每次重新写长路径;先提取引用:
const auto& data = j["response"]["data"]; for (size_t i = 0; i <p>注意点:</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill11499" title="cn-json-diff"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20cf0281539.jpg" alt="cn-json-diff" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill11499" title="cn-json-diff" class="overflowclass">cn-json-diff</a> <p class="overflowclass">比较两个 JSON 文件并显示差异。支持嵌套结构、数组及值变更。纯 Python 标准库实现,无需 API 密钥。</p> </div> <a rel="nofollow" href="/xiazai/skill11499" title="cn-json-diff" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>
-
const auto&是必须的,否则operator[]返回临时json对象,引用会悬空 - 如果后续会修改
j,就不能缓存引用,得用at()+ 异常处理保安全 - 深层嵌套下,
j["a"]["b"]["c"]每次都从根开始查,O(深度),缓存后降为 O(1)
当数组里混着不同结构的对象,用 is_number() 和 is_string() 区分字段语义
比如 API 返回的 "values" 数组可能含数字、字符串、对象三种类型,统一当对象取 ["id"] 会 crash。必须逐个判断类型再分支处理。
典型错误现象:what(): [json.exception.type_error.302] type must be object, but is number
正确做法:
for (const auto& v : j["values"]) {
if (v.is_number()) {
int id = v.get<int>();
} else if (v.is_string()) {
std::string s = v.get<:string>();
} else if (v.is_object()) {
int id = v.value("id", -1);
std::string name = v.value("name", "");
}
}
</:string></int>
嵌套越深,类型不确定性越高;靠文档假设类型,不如运行时检查实在。尤其对接第三方 API,字段类型随时可能变。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










