一、介绍
JSON起源于弱类型语言Javascript,它的产生来自于一种称之为"关联数组(Associative array)"的概念,其本质是就是采用"键值对"的方式来描述对象。
JSON格式保持了XML的人眼可读的优点,非常符合工程师对对象的理解。
相对于XML而言,序列化后的数据更加简洁(XML所产生序列化之后文件的大小接近JSON的两倍),而且其协议比较简单,解析速度比较快。
JSON格式具备Javascript的先天性支持,所以被广泛应用于Web browser的应用常景中,是Ajax的事实标准协议。
更多资料可查看:http://json.org/。
// json 是一种数据格式, 和语言无关
// 用途: 序列化网络通信数据, 编写配置文件
// 格式: json数组, json对象
// 注意事项: 在一个json文件中只能存储一个大的数组或对象,但是可以互相嵌套
// josn数组 -> [], 元素类型, 可以相同, 可以不同
// 支持的数据类型: int, float, double, string, bool, json数组, json对象
// json对象 -> {}, 里边是键值对
// 键值: 必须是字符串
// value值: int, float, double, string, bool, json数组, json对象
// 数组
[12, 19.8, true, "hello", ["a", "b", "c"], {"name":"xiaoming"}]
// 对象
{
"father":"zhangsan",
"mother":"李四",
"other":{
"爱好":["足球", "蓝求"],
"isman":true,
"age":12
}
}
二、安装
1、windows下安装
-
首先从github上下载源码
https://github.com/open-source-parsers/jsoncpp/releases
-
解压进入jsoncpp-0.10.7\makefiles\msvc2010
-
使用vs编译lib_json,成功后会生成debug目录,里面有静态库
2、linux下安装
- 执行sudo apt-get install libjsoncpp-dev 命令
- 头文件在/usr/include /jsoncpp/json 下
- 动态库在/usr/lib/x86_64-linux-gnu/
三、VS下使用JsonCpp
-
配置库路径
- 单击箭头指向的按钮,配置之前生成的debug目录。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FekbMiDg-1599527620774)(C:\Users\yy\AppData\Roaming\Typora\typora-user-images\1599469375787.png)]
- 也可以直接将静态库复制到当前项目文件中
-
配置头文件路径
单击上图中包含目录,找到jsoncpp的头文件目录,例如:E:\jsoncpp-0.10.7\jsoncpp-0.10.7\include
-
配置附加依赖项
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZWopuRTF-1599527620781)(file:///C:\Users\yy\AppData\Roaming\Tencent\Users\734774492\QQ\WinTemp\RichOle\U%U[O0X9}}@6`G4U93JG$42.png)]
四、JsonCpp类的使用
1、value类(封装json的数据类型)
// Json支持的数据类型
Type = {int, double, float, string, char*, bool, JsonArray, JsonObject}
// 构造函数
Value(Type t);
// 将Value对象转换成对应类型的数据
Type asType();
// 判断Value对象中存储的数据的类型
bool isType();
// 取值
// 格式化 -> 将对象转换为字符串
// 适合于查看信息或者写文件
std::string toStyledString() const;
2、reader类(封装json数据的读取)
// json格式字符串 -> Value对象
bool parse(const std::string& document, Value& root, bool collectComments = true);
bool parse(const char* beginDoc, const char* endDoc,
Value& root, bool collectComments = true);
bool parse(std::istream& is, Value& root, bool collectComments = true);
3、FastWriter(封装json数据的写入)
// 将Value对象中的数据格式化 -> 字符串
// 适合于网络数据的发送
std::string write(const Value& root);
五、案例
1、添加数据,并格式化为字符串输出
void jsonAdd()
{
Json::Value v;
//添加数据
v.append(5);
v.append(1.2);
v.append("hello world");
v.append(true);
//添加数组
Json::Value vArr;
vArr.append("a");
vArr.append("b");
vArr.append("c");
v.append(vArr);
//添加json对象
Json::Value vObj;
vObj["name"] = "张三";
vObj["age"] = 18;
v.append(vObj);
//将json对象转换为字符串
string str = v.toStyledString();
cout << "v style: " << str << endl;
//toStyledString会将字符串换行为容易阅读的格式,FastWriter不会换行
Json::FastWriter fw;
string jsonText = fw.write(v);
cout << "jsonText: " << jsonText << endl;
}
2、将数据写入文件,再从文件读出
Json::Value v;
//添加数据
v.append(5);
v.append(1.2);
v.append("hello world");
v.append(true);
//添加数组
Json::Value vArr;
vArr.append("a");
vArr.append("b");
vArr.append("c");
v.append(vArr);
//添加json对象
Json::Value vObj;
vObj["name"] = "张三";
vObj["age"] = 18;
v.append(vObj);
//写入文件
ofstream ofs("./test.json");
ofs << v.toStyledString();
//关闭文件
ofs.close();
//从文件中读取Json数据
ifstream ifs("./test.json");
//解析json数据
Json::Reader rd;
Json::Value root;
rd.parse(ifs, root);
// 3 打印输出
// 遍历数组
for (int i = 0; i < root.size(); ++i)
{
Value sub = root[i];
if (sub.isInt())
{
cout << sub.asInt() << " ";
}
else if (sub.isDouble())
{
cout << sub.asDouble() << " ";
}
else if (sub.isBool())
{
cout << sub.asBool() << " ";
}
else if (sub.isString())
{
cout << sub.asString() << " ";
}
else if (sub.isArray())
{
// 继续遍历这个子数组
for (int j = 0; j < sub.size(); ++j)
{
cout << sub[j].asString() << " ";
}
cout << endl;
}
else if (sub.isObject())
{
//如果读取的是对象,则必须知道key值
// 根据对象中的key, 打印value值
cout << sub["name"].asString() << ", "
<< sub["age"].asInt() << " ";
}
}
//关闭文件
ifs.close();