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本身不是线程安全的,所以多线程环境下需要设置同步机制
相关推荐
new Vue()几秒前
ES6中Promise的使用场景
开发语言·前端·javascript
Mr.Liu62 分钟前
小程序-使用 iconfont 图标库报错:Failed to load font
前端·微信小程序·小程序
lix的小鱼6 分钟前
Scala之Array数组
java·开发语言·后端·python·scala
喻师傅8 分钟前
Scala—数组(数组定义、数组常用方法等)— 用法详解
开发语言·scala
45W冲冲冲10 分钟前
WIN10+CMAKE+MinGW+Opencv/C++ 和VScode开发环境搭建
c++·vscode·opencv
anqi2713 分钟前
Scala 的Array 和 ArrayBuffer 集合
开发语言·后端·scala
Mr.Liu615 分钟前
小程序25- iconfont 字体图标的使用
前端·微信小程序·小程序
春蕾夏荷_72829772515 分钟前
MFC 对话框中显示CScrollView实例
c++·mfc·cscrollview
爱写代码的派大星17 分钟前
el-table :span-method 合并单元格(2.0)
前端·javascript·vue.js
柔弱女子爱java21 分钟前
XML文件(超详细):XML文件概念、作用、写法、如何用程序解析XML、写入XML、dom4j框架、DTD文档、schema文档
xml·java·开发语言·后端