​C++ JsonCpp库中Reader与Writer使用详解


JSON作为轻量级数据交换格式,在C++开发中常通过JsonCpp库进行解析与生成。本文结合代码示例,深入讲解Json::ReaderJson::Writer的核心用法,助你高效处理JSON数据


一、JsonCpp核心类简介
  1. ​**Json::Value**
    JSON数据的容器,可表示对象、数组、字符串、数值等所有类型。通过键或索引访问元素,如root["key"]root[0]
  2. ​**Json::Reader**
    用于将JSON字符串或文件解析为Json::Value对象,支持错误检测
  3. ​**Json::Writer**
    Json::Value序列化为字符串,主要子类:
    • ​**Json::StyledWriter**:格式化输出(带缩进和换行)
    • ​**Json::FastWriter**:紧凑输出(无格式,节省空间)

二、Reader的解析操作
1. 解析字符串
#include <json/json.h>
#include <string>

void ParseString() {
    const char* json_str = R"({"name":"Alice","age":30,"scores":[90,85,95]})";
    Json::Reader reader;
    Json::Value root;
    
    if (reader.parse(json_str, root)) {
        std::string name = root["name"].asString(); // "Alice"
        int age = root["age"].asInt();              // 30
        for (auto score : root["scores"]) {
            std::cout << score.asInt() << " ";     // 输出:90 85 95
        }
    } else {
        std::cerr << "解析失败: " << reader.getFormattedErrorMessages();
    }
}

说明

  • parse()返回bool表示解析结果,失败时通过getFormattedErrorMessages()获取错误详情
  • 支持多层嵌套,如root["data"]["sub_key"]访问对象中的对象
2. 解析文件
void ParseFile(const std::string& filename) {
    std::ifstream file(filename);
    Json::Reader reader;
    Json::Value root;
    
    if (reader.parse(file, root)) {
        std::string email = root["contact"]["email"].asString();
    } else {
        std::cerr << "文件解析失败!";
    }
}

注意:需确保文件路径正确且格式合法


三、Writer的生成操作
1. 生成格式化JSON(StyledWriter)
void GenerateStyledJSON() {
    Json::Value root;
    root["name"] = "Bob";
    root["skills"].append("C++");
    root["skills"].append("Python");
    
    Json::StyledWriter writer;
    std::string json_str = writer.write(root);
    // 输出带缩进的JSON字符串
    std::cout << json_str;
}

输出效果

{
   "name" : "Bob",
   "skills" : [ "C++", "Python" ]
}
2. 生成紧凑JSON(FastWriter)​
void GenerateCompactJSON() {
    Json::Value root;
    root["id"] = 1001;
    root["active"] = true;
    
    Json::FastWriter writer;
    std::string json_str = writer.write(root);
    // 输出:{"active":true,"id":1001}
}

适用场景:网络传输或存储空间敏感的场景


四、高级用法示例
1. 解析复杂JSON(含数组和嵌套)​
// JSON示例:{"data":[{"id":1,"tags":["A","B"]},{"id":2,"tags":["C"]}]}
void ParseComplexData(const Json::Value& root) {
    for (const auto& item : root["data"]) {
        int id = item["id"].asInt();
        for (const auto& tag : item["tags"]) {
            std::cout << tag.asString() << " ";
        }
    }
}
2. 动态构建JSON结构
void BuildDynamicJSON() {
    Json::Value root;
    root["timestamp"] = GetCurrentTime(); // 自定义函数
    
    Json::Value logs;
    logs.append("log1");
    logs.append("log2");
    root["logs"] = logs;
    
    // 输出为文件
    std::ofstream out("log.json");
    Json::StyledWriter().write(root, out);
}

五、注意事项
  1. 编码问题
    JsonCpp默认处理ANSI字符串,若使用Unicode需额外转码
  2. 性能优化
    • 解析大文件时,建议使用CharReaderBuilder流式解析(新API)
    • 频繁操作JSON时,复用Json::Value对象减少内存分配。
  3. 错误处理
    始终检查parse()返回值,避免访问不存在的键(可用isMember()验证)

六、总结

通过Json::ReaderJson::Writer,开发者能轻松实现:

  • 解析:字符串、文件、复杂嵌套结构。
  • 生成:格式化或紧凑的JSON数据。
  • 扩展:结合新API(如StreamWriterBuilder)满足高级需求
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值