手动拼接JSON必须转义6种字符:"→"、→\、、、 、 、 ;key和value需正确加双引号;数字/布尔/null不可加引号;递归序列化须防栈溢出和循环引用。

JSON字符串拼接必须手动处理哪些字符
直接用 + 拼接字符串生成 JSON 是可行的,但只要值里含 "、
、 、
、\ 或 Unicode 控制字符(如 U+0000–U+001F),就会破坏 JSON 结构。浏览器或 json.loads() 会直接报 Invalid character 或 Unterminated string。
核心转义规则只有 6 种必须处理:" → ",\ → \\,、、
、
、 各自映射为对应转义序列;其余 Unicode 字符可保留,但若需兼容老旧解析器,U+0000–U+001F 范围建议统一转成 uXXXX 形式。
实操建议:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- 别依赖
std::string::replace多次遍历——顺序错乱会导致\被重复转义(比如先替"再替,结果"变成\") - 用单趟遍历 +
std::ostringstream或预分配std::stringbuffer,边扫边写 - 对 ASCII 控制字符(0x00–0x1F)做查表判断比调用
std::iscntrl更快且确定
如何安全拼接 key 和 value 的双引号与冒号
JSON 要求所有 key 必须是双引号字符串,value 是字符串时也必须加双引号。漏掉任一引号,解析器就报 Unexpected token。常见错误是只给 value 加引号、key 忘加,或拼接时多套了一层引号导致 ""key"" 这种非法嵌套。
立即学习“C++免费学习笔记(深入)”;
实操建议:
- 写一个内联函数
quoted(const std::string& s),只负责加外层"并转义内容,不碰输入本身 - 拼接对象字段时固定用
quoted(key) + ":" + value_repr,其中value_repr已含引号(字符串)或无引号(数字/bool/null) - 避免用
fmt::format(R"("{}": "{}")", k, v)类模板——如果v是未转义字符串,引号会提前闭合
数字、布尔、null 值不能加引号,否则变成字符串
拼接时最容易犯的错:把 true、42、null 当作字符串拼进去,结果生成 "true"、"42"、"null"——这在 JSON 里是字符串字面量,不是布尔、数字或空值。解析后类型全错,前端 typeof data.flag === "string" 就会出问题。
实操建议:
- 为不同类型提供专用序列化函数:
to_json_string(const std::string&)、to_json_number(double)、to_json_bool(bool)、to_json_null() - 数字用
std::to_string不够——它不处理NaN、inf,也不控制精度。简单场景可用std::sprintf(buf, "%.17g", x);严谨点用std::ostringstream配std::setprecision(17)和std::scientific判定 - 布尔和 null 直接返回字面量字符串
"true"、"false"、"null",绝不可加引号
嵌套对象和数组的递归拼接容易栈溢出或无限循环
如果支持任意嵌套(比如传入 std::map 或自定义结构体),递归序列化时没设深度限制或没处理循环引用,遇到自引用对象(如树节点含 parent 指针)就会死循环,最终栈溢出崩溃。
实操建议:
- 递归函数加深度参数,超 100 层直接抛异常或截断,避免爆栈(JSON 规范没强制深度限制,但实际解析器通常设 100–1000 层)
- 若需支持循环引用,得引入外部状态记录已访问地址(如
std::set<const void></const>),遇到重复地址输出null或预留占位符(如"$ref": "#/path/to/node") - 数组拼接时注意末尾逗号:用 “先拼首项,再对后续每项前加
,” 的方式,比 “每项后加,再删最后一个” 更可靠
最易被忽略的是空字符串、全空白字符串、含 BOM 的 UTF-8 输入——它们看起来“什么都没有”,但转义后可能产生不可见控制字符,导致 JSON 校验失败。处理前先 trim 并检查是否为空,比硬转更稳妥。

















