C++怎么读写JSON_C++数据解析教程【热门】

2次阅读

绝大多数新项目选 nlohmann/json:免编译、头文件即用、c++11 全平台兼容;jsoncpp 需手动编译且易遇链接/版本问题;旧项目勿强行迁移,嵌入式场景体积差异微小,读 json 文件必须用 binary 模式。

C++怎么读写JSON_C++数据解析教程【热门】

用 nlohmann/json 还是 jsoncpp?选库前先看这三点

绝大多数新项目直接用 nlohmann/json,它免编译、头文件即用、C++11 起全平台兼容,2026 年已成事实标准。jsoncpp 需要手动编译静态/动态库,linux 下容易因 libjsoncpp.so 版本不匹配报 undefined symbol 错误,windows 上更常遇到 LNK2019 找不到 Json::Reader::parse 实现——本质是链接时漏了 libjsoncpp.lib 或 CMake 没正确 target_link_libraries

  • 已有旧项目用 jsoncpp:别强行替换,Json::Valuenlohmann::json 语义差异大,迁移成本高
  • 嵌入式或极端精简场景:jsoncpp 的二进制体积略小,但差距在百 KB 级,通常不构成决策依据
  • 需要中文键名或 UTF-8 原生支持:两个库都支持,但 jsoncpp 默认不校验 bom,读带 U+FEFF 的文件可能静默失败

读 JSON 文件时,ifstream 必须加 std::ios::binary 吗?

必须加。不加会导致 Windows 下读取含换行的 JSON(比如用 StyledWriter 格式化过的)时,rn 被 ifstream 自动转成 n,后续 Json::Reader::parse() 解析失败,报错类似 "invalid value" at line 1;nlohmann/json 虽然容错稍强,但遇到 BOM 或非 ASCII 字符仍可能解析出空对象

  • std::ifstream ifs("config.json", std::ios::binary); 是安全底线
  • 读完后不用 ifs.seekg(0) 回退——parse() 内部会处理流位置
  • 如果用 std::Filesystem::read_bytes(C++17),则完全绕过流问题,但需自行转 std::string_view

nlohmann::json::parse()jsoncpp::Reader::parse() 的错误处理差异

两者都返回布尔值表示成功,但错误信息暴露程度天差地别:nlohmann 提供 json::parse_Error 异常,能精确到第几行第几个字符;jsoncpp 只有 getFormattedErrorMessages() 返回字符串,且默认不开启详细模式,容易让开发者对着 "parse error" 空转。

  • nlohmann 示例:try { auto j = nlohmann::json::parse(ifs); } catch (const nlohmann::json::parse_error& e) { std::cerr
  • jsoncpp 必须显式启用:reader.parse(ifs, root, false); 第三个参数为 false 才输出完整错误上下文
  • 线上环境别依赖 std::cout 打印错误——JSON 解析失败往往发生在配置加载阶段,日志系统可能还没初始化

写 JSON 到文件时,格式化(pretty)和紧凑(compact)怎么选?

开发调试期无脑开 std::setw(2) 格式化;生产环境配置文件若被 Ansible/Chef 等工具 diff,紧凑模式可避免因空格/换行导致的误判;但注意:nlohmann 的 dump(2) 输出末尾带换行,jsoncpp 的 StyledWriter 不带——如果下游脚本用 head -n1 读首行,结果可能不一致。

立即学习C++免费学习笔记(深入)”;

  • nlohmann 写法:ofs (显式补换行更可控)
  • jsoncpp 写法:Json::StreamWriterBuilder wbuilder; wbuilder["indentation"] = " "; ofs
  • 别用 FastWriter 存含中文的配置——它不转义 Unicode,终端显示可能乱码,且某些 shell 工具会截断

真正麻烦的从来不是读写本身,而是 JSON 键名拼错、类型强制转换(比如把 "123"int 用)、数组越界访问这些运行时才暴露的问题。建议所有从 JSON 取值的地方都加 isXXX() 检查,哪怕多三行代码。

text=ZqhQzanResources