json字符串需先解析为对象模型才能安全操作,c++须用nlohmann/json等第三方库;删除键值对需递归遍历并校验类型,避免直接erase()或忽略嵌套结构。

JSON字符串不是C++原生类型,得先解析再操作
直接对std::string做“减去键值对”这种操作没有意义——JSON是结构化数据,必须先解析成可遍历的对象模型,否则删错位置、破坏嵌套结构、漏掉转义字符都是大概率事件。C++标准库不提供JSON支持,得依赖第三方库,jsoncpp、nlohmann/json(推荐)或rapidjson是主流选择。用nlohmann/json最省心:头文件即用,语法接近Python,且能精准定位嵌套路径。
用nlohmann/json删除指定key,注意路径和类型匹配
删除操作本质是递归查找+条件移除,不能只靠erase()一次调用搞定。比如想删掉所有"temp"字段,它可能出现在顶层、数组元素里、嵌套对象中,甚至同名但类型不同(string vs number)。正确做法是用find()配合is_object()/is_array()判断,再逐层处理:
#include <nlohmann>
using json = nlohmann::json;
<p>void remove_key_recursive(json& j, const std::string& key) {
if (j.is_object()) {
auto it = j.begin();
while (it != j.end()) {
if (it.key() == key) {
it = j.erase(it); // erase返回下一个有效迭代器
} else {
remove_key_recursive(it.value(), key);
++it;
}
}
} else if (j.is_array()) {
for (auto& item : j) {
remove_key_recursive(item, key);
}
}
}</p></nlohmann>
常见错误:j.erase("key")只删顶层;没检查is_object()就调begin()会崩溃;在for循环里用erase()后没调整迭代器导致跳项或越界。
删除后序列化回字符串,注意格式与编码
删完必须重新序列化,否则还是原始字符串。默认j.dump()生成紧凑格式(无空格),调试时可用j.dump(2)加缩进。若原始JSON含UTF-8 BOM或特殊控制字符,nlohmann/json默认按UTF-8处理,但输入字符串本身若含非法字节(如截断的UTF-8),解析阶段就会抛json::parse_error异常——得提前捕获:
- 用
try { json j = json::parse(s); } catch (const json::parse_error& e) { /* 处理错误 */ } - 确认输入字符串以
\0结尾且不含中间空字节(std::string允许\0,但json解析器会截断) - 若需保留原始空白(如注释、换行),
nlohmann/json不支持,得换jsonnet或手动字符串处理(极不推荐)
性能敏感场景慎用递归删除,考虑迭代式路径匹配
对超大JSON(>10MB)或高频调用,递归栈深和重复遍历开销明显。此时应改用路径表达式(如"$.data.items[*].temp"),配合json::json_pointer或第三方jsonpath库。但nlohmann/json原生只支持简单指针("/a/b/c"),不支持通配符。硬要实现就得手写状态机解析路径,或者预编译成节点引用列表——复杂度陡增,除非真卡在性能瓶颈,否则别过早优化。
真正容易被忽略的是:JSON键名区分大小写,"Temp"和"temp"是两个键;数组里删元素后索引会变,但json::array_t自动维护连续性,不用手动重排;还有,空对象{}或空数组[]删完可能残留,是否需要清理得单独判断。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










