目录
1. JSON
2. JSONcpp 的安装
3. JSONcpp 相关API的使用
3.1. 将 Json::Value 对象转化为 std::string
3.1.1. Json::Value 类
3.1.2. Json::Value::toStyledString 接口
3.1.3. Json::StyledWriter 类
3.1.4. Json::StyledWriter::write 接口
3.1.5. Json::FastWriter 类
3.2. 将 std::string 转化为 Json::Value 对象
3.2.1. Json::Reader 类
3.2.2. Json::Reader::parse 接口
1. JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript语言的子集,但是独立于编程语言,因此可以被多种编程语言支持和解析。JSON以易于人类阅读和编写的方式来表示数据,通常用于在网络之间传输数据。
JSON数据是以键值对的形式组织的,键值对之间用逗号分隔,键和值之间用冒号分隔,整个数据被包裹在大括号 {} 中。例如:
// 形式一:
{
"name" : "Xu Qian",
"age" : 22,
"city" : "Xi'an"
}
// 形式二:
{ "name" : "Xu Qian", "age" : 22, "city" : "Xi'an" }
2. JSONcpp 的安装
因为我们需要在 C++ 中解析和生成JSON数据, 因此我们需要安装 jsoncpp库, 用于处理JSON数据, 它提供了一组简单的API,可以方便地解析JSON字符串、生成JSON字符串以及在C++对象和JSON之间进行转换。
// 安装 jsoncpp 库
sudo yum install -y jsoncpp-devel
安装成功后,我们可以查看一下相关的库以及头文件。
jsoncpp 相关的库文件:
jsoncpp 相关的头文件:
3. JSONcpp 相关API的使用
3.1. 将 Json::Value 对象转化为 std::string
这个过程不就是一个序列化过程吗? 答案:是的。
3.1.1. Json::Value 类
Json::Value 是 JSONcpp 库中的一个类,用于表示 JSON 数据的任意类型。
在 JSONcpp 中,Json::Value 类是一个非常灵活的数据结构,可以表示 JSON 中的任何类型数据,包括对象、数组、字符串、数字、布尔值和空值。
例如:
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{
// 创建一个 Json::Value 对象
Json::Value root;
// 向 Json 对象添加键值对
root["name"] = "Xu Qian";
root["age"] = "22";
root["city"] = "Xi'an";
// 将 Json 对象转换为字符串并输出
std::string JsonString = root.toStyledString();
std::cout << "Json String: " << JsonString << std::endl;
return 0;
}
运行现象:
3.1.2. Json::Value::toStyledString 接口
函数原型:
std::string toStyledString() const;
在 Jsoncpp 中,toStyledString 是一个用于将 JSON 值格式化为带缩进和换行符的字符串的方法。
toStyledString 方法是 Json::Value 类的成员方法,Json::Value 实例化后的对象调用 toStyledString,会返回一个格式化后的字符串表示该 JSON 值。
格式化后的字符串包含了缩进和换行符,以便更容易阅读和理解。 就例如上面的运行现象一样。
3.1.3. Json::StyledWriter 类
Json::StyledWriter 是 JSONcpp 库中的一个类,用于将 Json::Value 对象中的 JSON 数据以美化的方式格式化为字符串输出。
在处理 JSON 数据时,通常我们希望输出的 JSON 字符串具有良好的可读性,以便于调试和理解。
而 Json::StyledWriter 类就提供了这样的功能,它会在输出的 JSON 字符串中添加缩进和换行,使得其结构更加清晰,易于阅读。
下面用实例用以说明:
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{
// 创建一个 Json::Value 对象
Json::Value root;
// 向 Json 对象添加键值对
root["name"] = "Xu Qian";
root["age"] = "22";
root["city"] = "Xi'an";
// 创建一个 Json::StyledWriter 对象
Json::StyledWriter writer;
// 通过该对象的write接口将 JSON 对象转换为美化的字符串并输出
std::string jsonString = writer.write(root);
std::cout << "Styled JSON String: " << jsonString << std::endl;
return 0;
}
现象如下:
3.1.4. Json::StyledWriter::write 接口
Json::StyledWriter::write 是 JSONcpp 库中 Json::StyledWriter 类的成员函数,用于将 Json::Value 对象中的 JSON 数据以美化的方式格式化为字符串输出。
函数原型:
std::string write(const Value &root) const;
- 参数 root 是一个 Json::Value 对象,它包含了需要被转换为 JSON 字符串的数据。该函数返回一个 std::string 类型的字符串,其中包含了以美化格式表示的 JSON 数据。
- 使用 Json::StyledWriter::write 函数,你可以将 Json::Value 对象中的 JSON 数据转换为易于阅读的字符串,以便于输出、保存或传输。这在调试和输出 JSON 数据时特别有用,因为美化的 JSON 字符串更容易被人类读取和理解。
3.1.5. Json::FastWriter 类
Json::FastWriter 是 JSONcpp 库中的一个类,用于将 Json::Value 对象中的 JSON 数据以一种更紧凑的方式格式化为字符串输出。
与 Json::StyledWriter 不同,Json::FastWriter 输出的 JSON 字符串不包含额外的空格、缩进或换行,因此更加紧凑,适合在需要减少字符串大小或传输速度较重要的情况下使用。
FastWriter 也有write接口,函数原型如下:
std::string write(const Value &root) const;
与 Json::StyledWriter::write 唯一不同的就是, 返回的字符串的格式不同罢了。
下面用实例说明:
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{
// 创建一个 Json::Value 对象
Json::Value root;
// 向 Json 对象添加键值对
root["name"] = "Xu Qian";
root["age"] = "22";
root["city"] = "Xi'an";
// 创建一个 Json::Value 对象
Json::Value score;
score["math"] = "85";
score["english"] = "76";
// 将score内嵌到root中
root["score"] = score;
// 创建一个 Json::FastWriter 对象
Json::FastWriter writer;
std::string jsonString = writer.write(root);
std::cout << "Styled JSON String: " << jsonString << std::endl;
return 0;
}
现象如下:
3.2. 将 std::string 转化为 Json::Value 对象
这个过程不就是一个反序列化的过程吗? 答案是的。
3.2.1. Json::Reader 类
- Json::Reader 是 Jsoncpp 库中的一个类,用于解析 JSON 字符串并将其转换为 Json::Value 对象。
- Json::Reader 类的主要作用是读取 JSON 字符串并将其解析为 Json::Value 对象。
- 它提供了一个 parse() 方法,可以接受一个 JSON 字符串作为参数,并尝试将其解析为一个 Json::Value 对象。
- 如果解析成功,parse() 方法将返回 true,并将解析后的 JSON 数据存储在提供的 Json::Value 对象中;
- 如果解析失败,parse() 方法将返回 false,并且可以通过调用 getFormattedErrorMessages() 方法获取解析错误的详细信息。
3.2.2. Json::Reader::parse 接口
Json::Reader::parse 是一个函数接口,用于将 JSON 字符串解析为 C++ 中的数据结构。它通常用于处理 JSON 数据的读取和解析操作。以下是该接口的函数原型:
bool Json::Reader::parse(const std::string& document, \
Json::Value& root, bool collectComments = true)
函数参数说明:
- document:要解析的 JSON 字符串。
- root:用于存储解析后的 JSON 数据的 Json::Value 对象。
- collectComments:一个布尔值,指示是否收集并保存 JSON 中的注释,默认为 true。如果为 true,则在解析过程中会保留 JSON 中的注释信息;如果为 false,则会忽略注释。
函数返回值:
- 如果解析成功,则返回 true;
- 如果解析失败,则返回 false。
接下来,我们以实例说明:
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{
// 这里的 \ 是一个转义字符, 让\" 用来表示 " 自身
std::string JsonString = "{\"name\" : \"Xu Qian\", \"age\" : 22, \"city\" : \"Xi'an\"}";
// 我们就需要通过 Jsoncpp 的相关API将
// 上面的JsonString 反序列化为特定数据
// 该对象用来存储解析后的JSON数据
Json::Value root;
// 定义一个 Json::Reader 对象
Json::Reader reader;
// 解析JsonString 并存储于root
reader.parse(JsonString, root);
// 提取name
std::string name = root["name"].asString();
// 提取age
int32_t age = root["age"].asInt();
// 提取name
std::string city = root["city"].asString();
std::cout << "name: " << name << std::endl;
std::cout << "age: " << age << std::endl;
std::cout << "city: " << city << std::endl;
return 0;
}
现象如下:
总而言之, 未来我们就可以用 Jsoncpp 来完成序列化和反序列化的功能。