JSONCPP 使用指南:在 C++ 中高效处理 JSON 数据
json广泛应用于 前后端通信、微服务间数据传输,所以熟悉json的格式和使用尤为重要
📦 目录
- 简介
- 安装与配置
- 核心用法
- 读取与解析 JSON
- 构建与输出 JSON
- 类型操作
- 错误处理
- 高级功能
- 注意事项
1️⃣ 简介
JsonCpp 是一个开源的 C++ 库(MIT License),提供:
- 完整的 JSON 解析/序列化功能
- DOM 风格接口
- SAX 风格解析器(0.y.z 版本后)
- 支持注释保留
- 精确的浮点数处理
GitHub仓库:open-source-parsers/jsoncpp
2️⃣ 安装与配置
Linux (Ubuntu/Debian)
sudo apt-get install libjsoncpp-dev
macOS (Homebrew)
brew install jsoncpp
Windows (vcpkg)
vcpkg install jsoncpp
CMake集成示例
可以参考这篇文章使用qt的方式编译
链接: libevent的编译
find_package(JsonCpp REQUIRED)
target_link_libraries(YourTarget PRIVATE JsonCpp::JsonCpp)
3️⃣ 核心用法
🔍 读取与解析 JSON
从字符串解析
#include <json/json.h>std::string jsonStr = R"({"name":"Alice","age":25,"scores":[90,85,95]})";
Json::Value root;
JSONCPP_STRING err;
Json::CharReaderBuilder builder;const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
if (!reader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.size(), &root, &err)) {std::cerr << "Parse error: " << err << std::endl;return -1;
}// 访问数据示例
std::cout << "Name: " << root["name"].asString() << std::endl; // Alice
从文件读取(推荐方式)
Json::Value root;
std::ifstream configFile("config.json");
configFile >> root; // 自动解析文件内容
🛠️ 构建与输出 JSON
构建JSON对象
Json::Value data;
data["name"] = "Bob";
data["age"] = 30;// 添加数组元素(两种方式)
data["hobbies"].append("reading");
data["hobbies"][1] = "swimming";// 添加嵌套对象
data["address"]["city"] = "New York";
data["address"]["zip"] = "10001";
JSON序列化输出(格式化)
Json::StreamWriterBuilder writerBuilder;
writerBuilder["indentation"] = "\t"; // 设置缩进格式const std::string output = Json::writeString(writerBuilder, data);
std::cout << output << std::endl;/* Output:
{"address" : {"city" : "New York","zip" : "10001"},"age" : 30,"hobbies" : [ "reading", "swimming"],"name" : "Bob"
}
*/
🔧 类型操作
Method | Description |
---|---|
isNull() | Check if value is null |
isArray() | Check if value is array |
isObject() | Check if value is object |
isNumeric() | Check if numeric type |
asInt() | Convert to int |
asFloat() | Convert to float |
asString() | Convert to string |
示例:
if (root.isMember("age") && root["age"].isInt()) {int age = root["age"].asInt();
}
else {// Handle missing or invalid field...
}
4️⃣ 错误处理最佳实践
Case1:异常捕获(启用 exceptions)
编译时需定义 JSON_USE_EXCEPTION=1
try {Json::Value root;std::cin >> root; // Invalid input will throw exception
} catch (const Json::Exception& e) {std::cerr << "Error: " << e.what() << std::endl;
}
Case2:空指针检测(禁用 exceptions)
Json::CharReaderBuilder builder;
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());if (!reader) {// Handle allocation failure...
}
5️⃣ 🔝高级功能
✨保留注释(0.y.z+版本)
Json::Value withComments;
Json::Reader reader;
reader.parse("{/* comment */}", withComments);// Write with comments preserved...
🌐宽松模式解析(允许非常规格式)
Json::CharReaderBuilder builder;
builder.settings_["allowComments"] = true;
builder.settings_["strictRoot"] = false;
🎨自定义写入器(扩展输出格式)
继承 Json::StreamWriter
:
class CustomWriter : public Json::StreamWriter {
protected:void writeValue(const Json::Value& value) override {// Custom implementation...}
};
6️⃣ ⚠️注意事项
-
跨平台差异
Windows下注意字符编码问题(建议统一使用UTF-8) -
性能优化
- SAX接口比DOM更节省内存
- Reuse
CharReader
/StreamWriter
instances when possible
-
内存管理
// Good practice: Json::Value* createData() {return new Json::Value(); // Manual management needed! }// Better use smart pointers: auto data = std::make_unique<Json::Value>();
-
版本兼容性
v1.y.z vs v0.y.z API有差异需注意
🎯总结
通过本文您已掌握:
✅ JSONCPP的基本使用方法
✅ JSON数据的高效处理技巧
✅常见问题的解决方案
官方文档参考:JSONCPP Documentation
在实际项目中推荐结合CMake进行依赖管理并编写完善的单元测试!