c++如何解析JSON c++ jsoncpp库使用教程【实例】

jsoncpp是C++中常用轻量JSON解析库,支持解析与序列化;安装方式因平台而异;基础解析推荐用Json::CharReaderBuilder和parseFromStream。

在 C++ 中解析 JSON,jsoncpp 是最常用、轻量且易上手的开源库之一。它支持读取(parse)和生成(serialize)JSON 数据,适合中小型项目快速集成。

一、安装 jsoncpp 库

不同平台安装方式略有差异:

  • Linux(Ubuntu/Debian):运行 sudo apt install libjsoncpp-dev
  • macOS(Homebrew):执行 brew install jsoncpp
  • Windows(vcpkg):用 vcpkg install jsoncpp
  • 源码编译:从 GitHub 官方仓库 下载,CMake 构建后链接 jsoncpp 静态或动态库

二、基础解析:读取 JSON 字符串

使用 Json::CharReaderBuilderJson::parseFromStream(推荐)或旧式 Json::Reader(已弃用)。

示例代码(解析一段用户信息):

立即学习“C++免费学习笔记(深入)”;

#include 
#include 
#include 

int main() {
    std::string jsonStr = R"({
        "name": "张三",
        "age": 28,
        "is_student": false,
        "courses": ["C++", "算法"]
    })";

    Json::CharReaderBuilder builder;
    JSONCPP_STRING errs;
    Json::Value root;

    std::istringstream iss(jsonStr);
    if (!Json::parseFromStream(builder, iss, &root, &errs)) {
        std::cerr << "JSON 解析失败:" << errs << std::endl;
        return -1;
    }

    // 提取字段(带类型安全检查)
    if (root.isObject()) {
        std::string name = root.get("name", "未知").asString();
        int age = root.get("age", 0).asInt();
        bool isStu = root.get("is_student", true).asBool();
        Json::Value courses = root["courses"];
        
        std::cout << "姓名:" << name << ", 年龄:" << age 
                  << ", 是否学生:" << (isStu ? "是" : "否") << std::endl;
        
        if (courses.isArray()) {
            std::cout << "课程:";
            for (const auto& course : courses) {
                std::cout << course.asString() << " ";
            }
            std::cout << std::endl;
        }
    }
    return 0;
}

三、写入 JSON:构建并序列化对象

Json::Value 构造结构,再通过 Json::StreamWriterBuilder 转为字符串。

  • 支持嵌套对象、数组、基本类型(string/int/bool/double/null)
  • root["key"] = value 可直接赋值;数组用 append() 或下标 root["arr"][i]
  • 输出格式可控制缩进(settings["indentation"] = " "
Json::Value root;
root["id"] = 1001;
root["active"] = true;
root["tags"].append("cpp");
root["tags"].append("json");

Json::StreamWriterBuilder builder;
builder["indentation"] = "  ";
std::string output = Json::writeString(builder, root);
std::cout << output << std::endl;
// 输出:
// {
//   "active" : true,
//   "id" : 1001,
//   "tags" : [ "cpp", "json" ]
// }

四、常见注意事项

避免运行时崩溃和逻辑错误的关键点:

  • 访问字段前先用 root.isMember("key") 判断是否存在,或用 get("key", default) 提供默认值
  • 数组索引越界会返回 null 值,调用 .asInt() 等可能抛异常 —— 建议配合 .isNull().isInt() 类型检查
  • 中文字符串需确保源文件保存为 UTF-8 编码,jsoncpp 默认按 UTF-8 处理,无需额外转码
  • 多线程环境下,Json::CharReaderBuilderJson::StreamWriterBuilder 实例非线程安全,建议每个线程独立创建

不复杂但容易忽略。把解析逻辑封装成函数,配合异常处理或返回状态码,就能稳定用于配置加载、网络响应解析等场景。