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本身不是线程安全的,所以多线程环境下需要设置同步机制
相关推荐
前端Hardy9 分钟前
HTML&CSS:惊艳!科技感爆棚的登录页面代码解析
前端·javascript·html
Jackilina_Stone10 分钟前
【faiss】用于高效相似性搜索和聚类的C++库 | 源码详解与编译安装
android·linux·c++·编译·faiss
双叶83611 分钟前
(Python)文件储存的认识,文件路径(文件储存基础教程)(Windows系统文件路径)(基础教程)
开发语言·windows·python
我是哈哈hh21 分钟前
【AJAX项目】黑马头条——数据管理平台
前端·javascript·ajax·前端框架·axios·proxy模式
喜欢吃燃面21 分钟前
C++:list(1)list的使用
开发语言·c++·学习
高端章鱼哥23 分钟前
分享一个 MySQL binlog 分析小工具
前端
Ronin-Lotus25 分钟前
上位机知识篇---AJAX
前端·javascript·ajax
Rika28 分钟前
手写mini-vue之后,我写了一份面试通关手册
前端·vue.js
我想说一句29 分钟前
使用React开发拉布布旅游智能聊天机器人的实践
前端·前端框架
wwy_frontend30 分钟前
积累:04-VUE2
前端