c++的jsoncpp使用

JSONCPP 使用指南:在 C++ 中高效处理 JSON 数据

json广泛应用于 前后端通信、微服务间数据传输,所以熟悉json的格式和使用尤为重要

📦 目录

  1. 简介
  2. 安装与配置
  3. 核心用法
    • [读取与解析 JSON](#读取与解析 JSON)
    • [构建与输出 JSON](#构建与输出 JSON)
    • 类型操作
  4. 错误处理
  5. 高级功能
  6. 注意事项

1️⃣ 简介

JsonCpp 是一个开源的 C++ 库(MIT License),提供:

  • 完整的 JSON 解析/序列化功能
  • DOM 风格接口
  • SAX 风格解析器(0.y.z 版本后)
  • 支持注释保留
  • 精确的浮点数处理

GitHub仓库:open-source-parsers/jsoncpp


2️⃣ 安装与配置

Linux (Ubuntu/Debian)

bash 复制代码
sudo apt-get install libjsoncpp-dev

macOS (Homebrew)

bash 复制代码
brew install jsoncpp

Windows (vcpkg)

powershell 复制代码
vcpkg install jsoncpp

CMake集成示例

可以参考这篇文章使用qt的方式编译

链接: libevent的编译

cmake 复制代码
find_package(JsonCpp REQUIRED)
target_link_libraries(YourTarget PRIVATE JsonCpp::JsonCpp)

3️⃣ 核心用法

🔍 读取与解析 JSON

从字符串解析
cpp 复制代码
#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
从文件读取(推荐方式)
cpp 复制代码
Json::Value root;
std::ifstream configFile("config.json");
configFile >> root; // 自动解析文件内容

🛠️ 构建与输出 JSON

构建JSON对象
cpp 复制代码
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序列化输出(格式化)
cpp 复制代码
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

示例:

cpp 复制代码
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

cpp 复制代码
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)

cpp 复制代码
Json::CharReaderBuilder builder;
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());

if (!reader) {
    // Handle allocation failure...
}

5️⃣ 🔝高级功能

✨保留注释(0.y.z+版本)

cpp 复制代码
Json::Value withComments;
Json::Reader reader;
reader.parse("{/* comment */}", withComments);

// Write with comments preserved...

🌐宽松模式解析(允许非常规格式)

cpp 复制代码
Json::CharReaderBuilder builder;
builder.settings_["allowComments"] = true;
builder.settings_["strictRoot"] = false;

🎨自定义写入器(扩展输出格式)

继承 Json::StreamWriter

cpp 复制代码
class CustomWriter : public Json::StreamWriter {
protected:
    void writeValue(const Json::Value& value) override {
        // Custom implementation...
    }
};

6️⃣ ⚠️注意事项

  1. 跨平台差异

    Windows下注意字符编码问题(建议统一使用UTF-8)

  2. 性能优化

    • SAX接口比DOM更节省内存
    • Reuse CharReader/StreamWriter instances when possible
  3. 内存管理

    cpp 复制代码
    // Good practice:
    Json::Value* createData() {
        return new Json::Value(); // Manual management needed!
    }
    
    // Better use smart pointers:
    auto data = std::make_unique<Json::Value>();
  4. 版本兼容性

    v1.y.z vs v0.y.z API有差异需注意


🎯总结

通过本文您已掌握:

✅ JSONCPP的基本使用方法

✅ JSON数据的高效处理技巧

✅常见问题的解决方案

官方文档参考:JSONCPP Documentation

在实际项目中推荐结合CMake进行依赖管理并编写完善的单元测试!

复制代码
相关推荐
XiaoHu020721 小时前
Linux多线程(详细全解)
linux·运维·服务器·开发语言·c++·git
苏宸啊21 小时前
C++(二)类和对象上篇
开发语言·c++
fqbqrr21 小时前
2601C++,编译时连接两个串指针
c++
superman超哥1 天前
双端迭代器(DoubleEndedIterator):Rust双向遍历的优雅实现
开发语言·后端·rust·双端迭代器·rust双向遍历
嵌入式进阶行者1 天前
【算法】TLV格式解析实例:华为OD机考双机位A卷 - TLV解析 Ⅱ
数据结构·c++·算法
OC溥哥9991 天前
Paper MinecraftV3.0重大更新(下界更新)我的世界C++2D版本隆重推出,拷贝即玩!
java·c++·算法
Jayden_Ruan1 天前
C++蛇形方阵
开发语言·c++·算法
星火开发设计1 天前
C++ map 全面解析与实战指南
java·数据结构·c++·学习·算法·map·知识
老鱼说AI1 天前
现代计算机系统1.2:程序的生命周期从 C/C++ 到 Rust
c语言·c++·算法
仰泳的熊猫1 天前
题目1099:校门外的树
数据结构·c++·算法·蓝桥杯