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进行依赖管理并编写完善的单元测试!

复制代码
相关推荐
FQNmxDG4S4 小时前
Java多线程编程:Thread与Runnable的并发控制
java·开发语言
前端老石人5 小时前
HTML 字符引用完全指南
开发语言·前端·html
matlab_xiaowang5 小时前
Redux 入门:JavaScript 可预测状态管理库
开发语言·javascript·其他·ecmascript
虹科网络安全5 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
axng pmje6 小时前
Java语法进阶
java·开发语言·jvm
汉克老师6 小时前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
老前端的功夫6 小时前
【Java从入门到入土】28:Stream API:告别for循环的新时代
java·开发语言·python
qq_435287926 小时前
第9章 夸父逐日与后羿射日:死循环与进程终止?十个太阳同时值班的并行冲突
java·开发语言·git·死循环·进程终止·并行冲突·夸父逐日
止语Lab6 小时前
从手动到框架:Go DI 演进的三个拐点
开发语言·后端·golang
yaoxin5211236 小时前
397. Java 文件操作基础 - 创建常规文件与临时文件
java·开发语言·python