用nlohmann::json读取本地JSON文件需先用std::ifstream打开并检查is_open(),再调用json::parse(ifs, nullptr, false)禁用异常,通过is_discarded()判断解析是否成功;访问嵌套字段应优先用at()或contains()校验存在性;整数读取推荐get<int64_t>()避免截断;Windows下需处理中文路径和UTF-8 BOM问题。

怎么用 nlohmann::json 读取本地 JSON 文件
直接调用 json::parse 配合文件流即可,但别跳过异常处理——JSON 格式错一个逗号就崩溃。
- 用
std::ifstream打开文件,检查是否成功(is_open()),否则json::parse会抛parse_error - 推荐用
json::parse(ifs, nullptr, false):第三个参数设为false可禁用异常,改用返回值判断解析是否成功 - 不要用
json j = json::parse(ifs)这种写法——一旦失败直接terminate,线上服务扛不住
std::ifstream ifs("config.json");
if (!ifs.is_open()) {
// 处理文件不存在或权限问题
}
nlohmann::json j = nlohmann::json::parse(ifs, nullptr, false);
if (j.is_discarded()) {
// 解析失败,j 为空且不可用
}
访问嵌套字段时为什么总报 out_of_range
因为 nlohmann::json 的 operator[] 在键不存在时**不报错也不返回 null,而是自动插入默认值**;真要安全访问,得用 at() 或先检查 contains()。
-
j["server"]["port"]:如果"server"不存在,会创建一个空对象,再取"port"得到null,后续转int就崩 -
j.at("server").at("port").get<int>():任一层缺失都抛out_of_range,适合明确要求字段必须存在 - 更稳的做法是:
j.contains("server") && j["server"].contains("port") && j["server"]["port"].is_number()
整数类型读取不准?get<int>() 和 get<int64_t>() 怎么选
JSON 规范里没有整型位宽概念,nlohmann 默认用 int64_t 存数字;但如果你直接 get<int>(),遇到超 INT_MAX 的值会静默截断——不报错,结果错得离谱。
- 配置中端口号、ID 类字段,优先用
get<long>()或get<int64_t>() - 如果确定是小整数(如开关标志
"debug": 1),可用get<int>(),但建议加范围校验:auto v = j["debug"].get<int>(); if (v != 0 && v != 1) { /* 拒绝非法值 */ } - 浮点字段别用
get<double>()强转整数——"timeout": 30.0可以,但"timeout": 30.5转int会丢精度
Windows 下中文路径或 UTF-8 BOM 导致解析失败
不是库的问题,是 C++ 标准文件流在 Windows 上默认按 ANSI 打开文件,含中文路径直接失败;BOM 则会让 json::parse 把开头三个字节当非法字符。
立即学习“C++免费学习笔记(深入)”;
- 路径含中文:用
std::wifstream+std::codecvt_utf8<wchar_t>转换,或改用跨平台路径 API(如std::filesystem::u8path+std::ifstream) - BOM 问题:读文件前跳过 UTF-8 BOM(
EF BB BF),三字节判断后 seekg(3) - 更省事的办法:统一用文本编辑器保存 JSON 为「UTF-8 无 BOM」格式,开发期就掐死源头
nlohmann/json 的坑不在语法难,而在它太“宽容”——自动补空对象、静默类型转换、不校验业务逻辑。真正上线前,每个配置字段都得过一遍「缺失、越界、类型错、编码乱」这四关。



















