不能直接用std::string手动拼json,因为易漏转义双引号、\n、中文等字符,导致json语法非法、解析失败或下游服务拒收;且std::string不保证utf-8完整性,无语法校验,错误延迟暴露。

C++ 没有标准 JSON 库,必须用第三方库;不选对库或不处理编码/内存,程序大概率崩溃或解析出错。
为什么不能直接用 std::string 手动拼 JSON
手动拼接容易漏转义(比如字符串里的 "、\n、中文),导致解析失败;更严重的是,生成的 JSON 可能语法非法,下游服务拒绝接收。JSON 格式看似简单,但引号嵌套、Unicode 处理、浮点数精度等细节极难手工控制。
- 双引号、反斜杠、控制字符(如
\u0000)必须严格转义 -
std::string默认不保证 UTF-8 编码完整性,含中文时易乱码 - 没有语法校验,错误只在运行时暴露(比如传给 HTTP 接口后返回 400)
推荐用 nlohmann/json:头文件即用,支持 C++11+
它把 JSON 当成一等公民来设计,json 类型可直接用 []、. 访问,自动推导类型,写起来接近 Python 或 JavaScript。编译期无依赖,只要把单个 json.hpp 加进工程就行。
示例:解析和构造
#include <nlohmann>
using json = nlohmann::json;
// 解析字符串
json j = json::parse(R"({"name":"张三","age":25,"hobbies":["coding","reading"]})");
std::string name = j["name"]; // 自动转 std::string
int age = j["age"]; // 自动转 int
std::vector<:string> hobs = j["hobbies"]; // 自动转 vector
// 构造 JSON
json out;
out["code"] = 200;
out["data"]["user_id"] = 1001;
out["data"]["tags"] = {"cpp", "json"};
std::string s = out.dump(2); // 格式化为缩进 2 的字符串
</:string></nlohmann>
- 访问不存在的 key 会抛
json::out_of_range异常,建议用j.value("key", default)安全取值 - 中文字符串必须确保源文件保存为 UTF-8(且无 BOM),否则
parse()可能失败 - 大 JSON(>10MB)解析时注意栈空间,默认递归深度有限,可调
json::parse(..., false)关闭异常抛出并手动检查
如果项目禁用异常或需极致性能,考虑 simdjson
simdjson 是为速度和零分配设计的,适合日志解析、高频数据通道等场景。但它不提供“自然”的对象访问语法,而是基于 DOM 或迭代器模型,学习成本更高,且要求 CPU 支持 AVX2(x86)或 ARM NEON。
- 必须预分配缓冲区:
simdjson::padded_string pstr = simdjson::padded_string::load("data.json"); - 解析后不能像
nlohmann那样随意读写,是只读 DOM,修改需重建 - 错误不靠异常,而是返回
simdjson::error_code,必须显式检查每一步 - 不支持直接从
std::string构造,必须用padded_string或document_stream
别忽略字符编码和构建配置
Windows 下 MSVC 默认用 GBK 编码读源文件,而 nlohmann/json 假设输入是 UTF-8。如果 JSON 字符串字面量含中文,又没设置编译选项,就会解析失败或显示为乱码。
- Clang/GCC:加
-finput-charset=UTF-8 - MSVC:源文件存为 UTF-8 with BOM,或加
/utf-8编译开关 - CMake 中统一设置:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -finput-charset=UTF-8") - 运行时读文件,务必用二进制模式打开,再用
std::string载入,避免文本模式自动换行转换破坏 JSON 结构
最常被跳过的其实是编码一致性——同一个 JSON 字符串,在编辑器里看着正常,编译进去就出错,十次有八次是编码没对齐。库只是工具,底下的字节流才是真相。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











