目录
前置知识
Json数据格式
JsonCpp介绍
安装jsoncpp库
头文件
使用介绍
使用示例
序列化
反序列化
前置知识
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数据对象类的表示:
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对象
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对象
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反序列化成功
使用示例
序列化
#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
结果如下:
root@ubuntu:~/demo/jsoncpp# ./json
{"姓名" : "张三","年龄" : 19,"成绩" : [100,100,100],"爱好" : {"书籍" : "骆驼祥子","运动" : "打羽毛球"}
}
注意:
- Json::StreamWriterBuilder工厂类返回的是Json::StreamWriter的指针,因此我们使用完Json::StreamWriter对象后要记得释放,这里采用智能指针对其进行管理。
反序列化
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;
}