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本身不是线程安全的,所以多线程环境下需要设置同步机制
相关推荐
全栈胖叔叔-瓜州1 小时前
关于llamasharp 大模型多轮对话,模型对话无法终止,或者输出角色标识User:,或者System等角色标识问题。
前端·人工智能
小鸡吃米…1 小时前
Python 列表
开发语言·python
三七吃山漆1 小时前
攻防世界——wife_wife
前端·javascript·web安全·网络安全·ctf
用户47949283569151 小时前
面试官问"try-catch影响性能吗",我用数据打脸
前端·javascript·面试
kaikaile19951 小时前
基于C#实现一维码和二维码打印程序
开发语言·c#
GISer_Jing2 小时前
前端营销技术实战:数据+AI实战指南
前端·javascript·人工智能
我不是程序猿儿2 小时前
【C#】画图控件的FormsPlot中的Refresh功能调用消耗时间不一致缘由
开发语言·c#
rit84324992 小时前
C# Socket 聊天室(含文件传输)
服务器·开发语言·c#
GIS之路2 小时前
使用命令行工具 ogr2ogr 将 CSV 转换为 Shp 数据(二)
前端
kk哥88992 小时前
C++ 对象 核心介绍
java·jvm·c++