目录
1.介绍
2.格式
3.底层
3.1数据对象表示
3.2序列化接口
3.3反序列化接口
4.使用
1.介绍
Json(JavaScript Object Notation)是一种轻量级的数据交换格式,其最早是为JavaScript编程语言设计的格式。不过发发展至今,Json数据格式已经成为了一种独立于语言的文本格式来存储和表示数据。
2.格式
假设,当我们需要表达个人信息时,我们在c语言中常用的做法是设计结构体来进行表述。例如:我们设计student结构体类定义和表述个人信息。
typedef struct {
int id;
char* name;
float score[3];
}student;
int main() {
student s1 = { 1,"张三",{77.7, 88.8, 99.9} };
return 0;
}
于是我们便得到了一种封装的学生数据格式,Json提供的也是类似的操作,将数据封装打包。
Json的数据表示形式我们可以通过一段代码来进行查看。
#include<iostream>
#include<string>
#include<memory>
#include<sstream>
#include<jsoncpp/json/json.h>
bool serialize(const Json::Value &root, std::string *out) {
//Json::StreamWriter
Json::StreamWriterBuilder swb;
std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
std::stringstream ss;
int ret = sw->write(root, &ss);
if (ret != 0) {
std::cerr << "serializer failed\n";
return false;
}
*out = ss.str();
return true;
}
int main() {
Json::Value root;
root["id"] = 1;
root["name"] = "张三";
root["score"].append(77.7);
root["score"].append(88.8);
root["score"].append(99.9);
std::string body;
serialize(root, &body);
std::cout << body << std::endl;
return 0;
}
现在我们不用关心上述代码的内容,主要是来查看经过Json组织的数据格式,我们将body打印,得到Json格式的数据如下:
红色框中的内容便是Json数据格式的内容,我们对其进行逐一介绍。
- Json当中的每位数据对象都是使用{}形容的内容,一个{}表示一个对象;
- Json当中每位对象中的数组是使用[]形容的内容,一个[]表示一个数组;
- Json当中的字符串使用常规""形容的内容,一个""表示一个字符串;
- Json当中的数字无论数据类型(整形和浮点型等),都是直接表示。
3.底层
了解Json使用之前,我们需要明白Json底层代码的实现逻辑。不用深究,只需要明白如何使用以及使用效果即可。
3.1数据对象表示
在Json当中的value.h当中,对[]和=进行了重载,于是我们便可以通过这两种运算符对Json格式数据当中内容进行赋值:
并且Json为我们提供了许多常用的接口,如下:
提供移除元素的removerMemvber接口:
提供添加元素的append接口:
提供获取元素个数的size接口:
提供转string的asString接口和转char *的asCstring接口:
以及提供转int、float和bool的asInt接口、asFloat接口和asBool接口:
3.2序列化接口
首先是JSON_API StreamWriter当中的writer接口和实例化:
3.3反序列化接口
JSON_API CharReader当中的parse接口和实例化:
4.使用
在大致了解完Json的内容之后,我们可以结合上文中展示Json数据格式的代码,来对Json的使用进行一个示例展示,具体代码设计如下:
#include<iostream>
#include<string>
#include<memory>
#include<sstream>
#include<jsoncpp/json/json.h>
bool serialize(const Json::Value &root, std::string *out) {
//Json::StreamWriter
Json::StreamWriterBuilder swb;
swb["commentStyle"] = "None";
swb["indentation"] = "";
std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
std::stringstream ss;
int ret = sw->write(root, &ss);
if (ret != 0) {
std::cerr << "serializer failed\n";
return false;
}
*out = ss.str();
return true;
}
bool unserialize(const std::string &out, Json::Value *root) {
//Json::CharReader
Json::CharReaderBuilder crb;
std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
std::string err;
bool ret = cr->parse(out.c_str(), out.c_str() + out.size(), root, &err);
if (ret == false) {
std::cerr << err << std::endl;
return false;
}
return true;
}
int main() {
Json::Value root;
root["id"] = 1;
root["name"] = "张三";
root["score"].append(77.7);
root["score"].append(88.8);
root["score"].append(99.9);
std::string body;
serialize(root, &body);
std::cout << body << std::endl;
Json::Value val;
unserialize(body, &val);
if (!val["id"].isNull())
std::cout << "id:" << val["id"].asInt() << "\t";
if (!val["name"].isNull())
std::cout << "name:" << val["name"].asString() << "\t";
if (!val["score"].isNull()) {
std::cout << "score:";
for (int i = 0; i < val["score"].size(); i++) {
std::cout << val["score"][i].asFloat() << "\t";
}
}
return 0;
}
从代码角度出发,我们先是定义Json数据格式的对象root,并对其进行赋值;然后定义body字符串,对Json类型数据root进行序列化之后保存到body当中,并打印查看Json格式下的数据内容;再定义val字符串,将Json类型数据root进行反序列化后保存val当中,并对val当中内容进行打印展示。
最后程序输出结果如下:
对于Json数据内容的打印,为便于展示我们对其进行了修改,取消了其中的换行和水平制表字符,所以显示打印结果在同一行。这也Json库提供的对外定义方式,在库中的定义如下:
在上述代码中定义的内容是:
是将换行取消,然后取消对象当中数据之间间隔。