目录
前置知识
Json数据格式
Json数据格式是一种数据交换格式,采用完全独立于编程语言的文本格式存储和表示数据。
例如:表示一个学生信息
{
"姓名":"xxx",
"年龄":18,
"成绩":[88.5,99,58]
}
Json的数据类型包括对象,字符串,数字等
- 对象:使用花括号{ }括起来的表示一个对象
- 数组:使用中括号[ ]括起来的表示一个数组
- 字符串:使用常规双引号""括起来的一个字符串
- 数字:包括整型和浮点型,直接使用
JsonCpp介绍
安装jsoncpp库
Linux环境下(ubuntu)
sudo apt-get install libjsoncpp-dev
头文件
在使用前,需要先引入jsoncpp的头文件
#include<jsoncpp/json/json.h>
使用介绍
JsonCpp库是用来实现Json数据格式的序列化和反序列化,主要涉及三个类:
1、Json::Value类:中间数据存储类
如果要将数据进行序列化,就需要先存储到Json::Value对象中;
如果要将数据进行反序列化,就是解析后,将数据对象放入到Json::Value对象中
如下是Json数据对象类的表示:
cpp
class Json::Value{
Value &operator=(const Value &other); //Value重载了[]和=,因此所有的赋值和获取
数据都可以通过
Value& operator[](const std::string& key);//简单的⽅式完成 val["name"] =
"xx";
Value& operator[](const char* key);
Value removeMember(const char* key);//移除元素
const Value& operator[](ArrayIndex index) const; //val["score"][0]
Value& append(const Value& value);//添加数组元素val["score"].append(88);
ArrayIndex size() const;//获取数组元素个数 val["score"].size();
std::string asString() const;//转string string name = val["name"].asString();
const char* asCString() const;//转char* char *name = val["name"].asCString();
Int asInt() const;//转int int age = val["age"].asInt();
float asFloat() const;//转float float weight = val["weight"].asFloat();
bool asBool() const;//转 bool bool ok = val["ok"].asBool();
};
2、序列化接口
- Json::StreamWriter类:用于进行数据序列化
- Json::StreamWriter::write() 序列化函数
- Json::StreamWriterBuilder类:Json::StreamWriter工厂类,用于生产一个Json::StreamWriter对象
cpp
class JSON_API StreamWriter {
virtual int write(Value const& root, std::ostream* sout) = 0;
}
//工厂类,生成一个StreamWriter对象
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
virtual StreamWriter* newStreamWriter() const;
}
PS:
virtual int write(要序列化的Json::Value对象, 输出流对象地址) = 0;
- 返回0序列化成功
3、反序列接口
- Json::CharReader反序列化类
- Json::CharReader::parse()反序列化函数
- Json::CharReaderBuilder 工厂类,用于生产一个Json::CharReader对象
cpp
class JSON_API CharReader {
virtual bool parse(char const* beginDoc, char const* endDoc,
Value* root, std::string* errs) = 0;
}
//工厂类
class JSON_API CharReaderBuilder : public CharReader::Factory {
virtual CharReader* newCharReader() const;
}
PS:
virtual bool parse((序列化后的字符串)字符串的起始地址, 字符串的结束地址,存放解析结果的Json::Value对象的地址,erro信息)
- 返回true反序列化成功
使用示例
序列化
cpp
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>
bool serialize(Json::Value &val,std::string &body)
{
std::stringstream ss;
//先实例化一个工厂类对象
Json::StreamWriterBuilder swb;
//获取一个StreamWriter对象
std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
int ret=sw->write(val,&ss);
if(ret!=0)
{
std::cout<<"serialize failed!"<<std::endl;
return false;
}
body=ss.str();
return true;
}
int main()
{
Json::Value student;
Json::Value fav;//描述爱好
//填入爱好
fav["书籍"]="骆驼祥子";
fav["运动"]="打羽毛球";
student["姓名"]="张三";
student["年龄"]=19;
//数组不能直接赋值,需要使用append方法
student["成绩"].append(100);
student["成绩"].append(100);
student["成绩"].append(100);
//嵌套一个对象
student["爱好"]=fav;
std::string body;
if(serialize(student,body))
{
std::cout<<body<<std::endl;
}
return 0;
}
编译运行
g++ -std=c++11 jsoncpp_test.cc -o json -ljsoncpp
结果如下:
bash
root@ubuntu:~/demo/jsoncpp# ./json
{
"姓名" : "张三",
"年龄" : 19,
"成绩" :
[
100,
100,
100
],
"爱好" :
{
"书籍" : "骆驼祥子",
"运动" : "打羽毛球"
}
}
注意:
- Json::StreamWriterBuilder工厂类返回的是Json::StreamWriter的指针,因此我们使用完Json::StreamWriter对象后要记得释放,这里采用智能指针对其进行管理。
反序列化
cpp
bool unserialize(const std::string &body,Json::Value &val)
{
//创建Json::CharReaderBuilder 工厂类
Json::CharReaderBuilder crb;
//获取一个Json::CharReader对象
std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
std::string errs;
bool ret=cr->parse(body.c_str(),body.c_str()+body.size(),&val,&errs);
if(ret==false)
{
std::cout<<"json unserialize failed:"<<errs<<std::endl;
return false;
}
return true;
}
int main()
{
std::string str=R"({"姓名":"张三","年龄":19,"成绩":[100,100,99]})";
Json::Value val;
if(unserialize(str,val))
{
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;
}