雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

C++中对JSON格式的解析以及序列化和反序列化

2024-06-16 62

前言

JSON是很常用的数据格式,在C++中我们可以使用nlohmann json做序列化和反序列化。
nlohmann json是一个跨平台的开源的C++ JSON解析库,只需要在项目中#include json.hpp文件就可以使用了。
github上面的文档非常详细,你也可以通过本文对nlohmann json有个基本了解,本文涵盖了日常编码中会用json库处理的大部分操作,如构造json对象、查找键值、序列化与反序列。
github地址: https://github.com/nlohmann/json

nlohmann json基础操作

由basic value创建json value

 using nlohmann::json;
 //方式一:
 json j1;
 j[name]=LeBorn Jame;//字符串
 j[number]=23;//整数
 j[man]=true;//布尔值
 j[children]={LeBorn Jr,Bryce Maximus,Zhuri};//数组
 j[behavior][funny]=gigigigigigi;//对象中元素值
 j[wife]={{name,Savannah Brinson},{man,false}};//对象
 
 //方式二
 json j2={
 {name,LeBorn Jame},
 {number,23},
  {man,true},
 {children,{LeBorn Jr,Bryce Maximus,Zhuri}},
 {behavior,{{funny,gigigigigigi}};
 {wife,{{name,Savannah Brinson},{man,false}}}
 };

由json value得到basic value

 using nlohmann::json;
 json j={
 {name,LeBorn Jame},
 {number,23},
 {children,{LeBorn Jr,Bryce Maximus,Zhuri}},
 {man,true},
 {wife,{name,Savannah Brinson}}
 };
 auto name=j[name].getstd::string();//方式一
 int number=0;
 j[number].get_to(number);//方式二
 auto childOne = j[children][0].getstd::string();//获取数组元素方式一,越界后不会抛出异常,直接中断
 auto childTwo=j[children].at(1).getstd::string();//越界后抛出异常
 auto wifeName=j[wife][name].getstd::string();
 
//bool man=j[man];//不推荐使用这种隐式转换的方式

像操作stl container一样操作json value

using nlohmann::json;
json animalArray={cat,dog};//定义一个数组类型的json对象
animalArray.push_back(pig);//添加元素
animalArray.emplace_back(duck);//C++11新方式添加元素,减少申请内存
//使用is_array()函数判断对象类型,使用empty函数判断数量是否为空
if(animalArray.is_array()  !animalArray.empty())
{
    auto size=animalArray.size();//使用size函数获取元素数量
    auto animalLast=animalArray.at([size-1]).getstd::string();
}

json animalObject={{kind,dog},{height,50}};//定义一个对象类型的json对象
animalObject.emplace({color,red});//插入元素
animalObject.erase(kind);//删除键值

//判断是否含有某个键值方式一
if(animalObject.contains(height))//通过contains函数判断是否包含某个key
{
    auto height=animalObject[height].getdouble();
}
//判断是否含有某个键值方式二
auto size=animalObject.count(height);//通过count函数计算某一个键的数量
if(size0)
{
    
}
//判断是否含有某个键值方式三
auto iter=animalObject.find(height);//通过find函数查找某个键的迭代器
if(iter!=animalObject.end()
{
    
}
//遍历输出键值方式一
for(auto item:animalObject.items())
{
    std::coutitem.key() item.value()std::endl;
}
//遍历输出键值方式2
for(auto iter=animalObject.begin();iter!=animalObject.end();++iter)
{
    std::coutiter-key() iter-value()std::endl;
}
//遍历输出键值方式3(C++17)
for(auto[key,value]:animalObject.keys())
{
    std::coutkey valuestd::endl;
}

序列化与反序列化(Serialization/Deserialization)

json value和string

using nlohmann::json;
//反序列化(Deserialization):_json/parse()
json j1={\kind\:\dog\,\height\:50}_json;//方式一,通过_json实现
json j2=R({kind:dog,height:50});//使用原生字符串关键字R来避免转移字符,但这一句并没有序列化,j2只保存字符串而已
json j3=json::parse(R({kind:dog,height:50}));//方式二,通过静态函数parse实现。
//使用 parse 函数时,如果字符串不符合 json 规范导致解析失败,默认会抛出异常,可以使用 try...catch 结构捕获异常进行处理;或者设置 parse 函数的第三个函数参数为 false,此时解析失败不会抛出异常,但解析得到的结果为 null。

//序列化(Serialization):dump(number),number为打印出的空格数
std::string animal1=j1.dump();//animal1值为{kind:dog,height:50}
std::string animal2=j1.dump(4);
//animal2值为
// {
//      kind:dog,
//      height:50,
// }

json value和streams

using nlohmann::json;
//反序列化(Deserialization):
json j1;
std::cinj1;

//序列化(Seriralization):
std::coutj1;

//上述操作适用于istream和ostream的子类,比如我们经常会用到的ifstream和ofstream
std::ifstream in(animals.json);//打开文件,关联到流in
json animals;
inanimals;
animals.at(0)[height]=60;//修改数据
in.close();

std::ofstream out(animal.json);//打开文件,关联到流out
outstd::setw(4)animals;//输出信息,std::setw(4)用于设置增加打印空格
out.close();

json value和自定义对象

在自定义对象命名空间中定义两个函数即可像basic value一样进行反序列化和序列化:from_json(const json j,T value)、to_json(json j,const T value)

//Animal.h文件
//定义Animal类,其包含两个成员变量kind与height
using nlohmann::json;
class Animal
{
    public:
        Animal(std::string kind,double height){
            this-kind=kind;
            this-height=height;
        }
    std::string kind;
    double height;
}
//定义from_json(const json j,T value)函数,用于序列化
void from_json(const json j,Animal animal)
{
    animal.kind=j[kind].getstd::string();
    animal.height=j[height].getdouble();
}

//定义to_json(json j,const T value)函数,用于反序列化
void to_json(json j,const Animal animal)
{
    j[kind]=animal.kind;
    j[height]=animal.height;
}

//main.cpp文件
int main()
{
    Animal animal{dog,50};
    nlohmnn::json j=animal;//像basic value一样将自定义对象赋值给json value
    j[height]=60;//修改数据
    Animal animalNew = j.getAnimal();//像basic value一样通过get函数获取值,将其值直接赋值给自定义对象
    std::coutanimal.height;//输出60
    return 0;
}

更新于:3个月前
赞一波!3

文章评论

全部评论