JSONCPP 数据解析与序列化

常用类接口

Json::Value 类

用于存储 JSON 数据的核心类。它支持将数据解析为对象、数组或基本类型(如字符串、数值等)

赋值操作符:Value& operator=(Value other);

用于将一个 JSON 值赋给另一个 JSON 值

cpp 复制代码
Json::Value value;
value = "Hello, World!";

访问操作符:Value& operator[](const char* key);

用于访问或设置对象属性的值

cpp 复制代码
Json::Value value;
value["姓名"] = "张三";

数组追加:Value& append(const Value& value);

向数组类型的 Value 添加新元素

cpp 复制代码
Json::Value value;
value["成绩"].append(88);

获取字符串值:std::string asString() const;

Value 转换为字符串

cpp 复制代码
std::string name = value["姓名"].asString();

获取数组大小:ArrayIndex size() const;

返回数组类型的 Value 的元素个数

cpp 复制代码
Json::Value value;
value["成绩"].append(88);
value["成绩"].append(76);
std::cout << value["成绩"].size(); // 输出:2

通过下标访问数组元素:Value& operator[](ArrayIndex index);

用于访问数组中的某个元素

cpp 复制代码
float score = value["成绩"][0].asFloat();

Write类

Writer 类负责将 Json::Value 对象序列化为字符串或流输出

StreamWriter 接口

  • 用于实现自定义的序列化逻辑
  • root:要序列化的 JSON 对象
  • sout:输出流
cpp 复制代码
virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;

StreamWriterBuilder

通过工厂方法生成 StreamWriter 对象

cpp 复制代码
StreamWriter* newStreamWriter();
cpp 复制代码
Json::StreamWriterBuilder builder;
std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
writer->write(value, &std::cout);

Reader类

CharReader 接口

定义了从字符串解析 JSON 数据的核心方法

  • beginDocendDoc:指向 JSON 文本的起始和结束位置
  • root:解析后的 JSON 数据存放的目标 Value 对象
  • errs:解析过程中的错误信息
cpp 复制代码
virtual bool parse(char const* beginDoc, char const* endDoc,
                   Value* root, JSONCPP_STRING* errs) = 0;

CharReaderBuilder

提供生成 CharReader 对象的工厂方法

cpp 复制代码
CharReader* newCharReader();


//事例使用
Json::CharReaderBuilder builder;
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
Json::Value root;
std::string errors;
std::string jsonText = R"({"name": "张三", "age": 25})";
reader->parse(jsonText.c_str(), jsonText.c_str() + jsonText.size(), &root, &errors);

基本使用

序列化

cpp 复制代码
#include<json/json.h>
#include<memory>
#include<sstream>
#include<iostream>

using namespace std;

bool Serialize(const Json::Value &val,std::string &dst)
{
    Json::StreamWriterBuilder swb;
    swb.settings_["emitUTF8"] = true;
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

    std::stringstream ss;
    int ret = sw->write(val,&ss);
    if(ret != 0){
        std::cout<<"Json 反序列化失败\n";
        return false;
    }
    dst = ss.str();
    return true;
}

int main()
{
    char name[] = "猪猪侠";
    int age = 18;
    float score[3] = {0,100,20};

    Json::Value stu;
    stu["姓名"] = name;
    stu["年龄"] = age;
    stu["成绩"].append(score[0]);
    stu["成绩"].append(score[1]);
    stu["成绩"].append(score[2]);

    std::string stu_str;
    bool ret = Serialize(stu,stu_str);
    if(ret == false) return -1;
    std::cout<<stu_str <<std::endl;
    return 0;
}

反序列化

cpp 复制代码
#include<json/json.h>
#include<memory>
#include<sstream>
#include<iostream>

using namespace std;

bool Serialize(const Json::Value &val,std::string &dst)
{
    Json::StreamWriterBuilder swb;
    swb.settings_["emitUTF8"] = true;
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

    std::stringstream ss;
    int ret = sw->write(val,&ss);
    if(ret != 0){
        std::cout<<"Json 反序列化失败\n";
        return false;
    }
    dst = ss.str();
    return true;
}

bool UnSerialize(const std::string &src , Json::Value &val)
{
    Json::CharReaderBuilder crb;
    crb.settings_["emitUTF8"] = true;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    std::string err;
    bool ret = cr->parse(src.c_str(),src.c_str()+src.size(),&val,&err);
    if(ret == false){
        std::cout<<"Json反序列化失败"<<err<<std::endl;
        return false;
    }
    return true;
}

int main()
{
    char name[] = "猪猪侠";
    int age = 18;
    float score[3] = {0,100,20};

    Json::Value stu;
    stu["姓名"] = name;
    stu["年龄"] = age;
    stu["成绩"].append(score[0]);
    stu["成绩"].append(score[1]);
    stu["成绩"].append(score[2]);

    std::string stu_str;
    bool ret = Serialize(stu,stu_str);
    if(ret == false) return -1;
    std::cout<<stu_str <<std::endl;

    Json::Value val;
    ret = UnSerialize(stu_str,val);
    if(ret == false) return -1;
    std::cout<<val["姓名"].asString()<<std::endl;
    std::cout<<val["年龄"].asInt()<<std::endl;
    int sz = val["成绩"].size();
    for(int i =0;i<sz;++i)
    {
        std::cout<<val["成绩"][i].asFloat()<<std::endl;
    }
    return 0;
}

JSONCPP局限性了解

  • 内存开销大,因为其需要非常大的JSON数据集
  • 高性能场景下还是选择更加轻量化的方案
  • JSONCPP本身不是线程安全的,所以多线程环境下需要设置同步机制
相关推荐
永不停转9 分钟前
借助 QT 的反射机制实现数据类的序列化
c++·qt
anyup_前端梦工厂14 分钟前
前端单元测试实战:如何开始?
前端·单元测试
拖孩18 分钟前
【Nova UI】十、打造组件库第一个组件-图标组件(下):从.svg 到 SVG Vue 组件的高效蜕变✨
前端·javascript·vue.js
柠石榴25 分钟前
【python编程从入门到到实践】第四章 操作列表
开发语言·python
独立开阀者_FwtCoder26 分钟前
一张图讲清楚:Manus的技术架构
前端·javascript·面试
小鱼人爱编程27 分钟前
AI🔥助我!三分钟实现丐版前后端注册登录需求
前端·后端·deepseek
独立开阀者_FwtCoder29 分钟前
【CSS】2327- CSS view():JavaScript 滚动动画的终结
前端·javascript·github
盛夏绽放30 分钟前
uni-app 状态管理深度解析:Vuex 与全局方案实战指南
前端·javascript·uni-app
Mr_兔子先生31 分钟前
2025盛夏版:Next.js15+Antd5开发部署SSR网站速通教程
前端·react.js·next.js
虾球xz34 分钟前
游戏引擎学习第232天
c++·学习·游戏引擎