接前一篇文章:C++常用容器、函数、类集(7)
本文内容参考:
C++中JSON文件处理教程:nlohmann/json库实战-CSDN博客
特此致谢!
17. nlohmann::json
(1)背景知识
JSON(JavaScript Object Notation)是Web服务中常用的轻量级数据交换格式。由于其可读性高、易于人阅读和编写,同时也易于机器解析和生成,因此成为了跨平台、跨语言数据交换的标准之一。它是一种基于文本的数据格式,被广泛地应用于Web API和配置文件中。
JSON的结构简单而强大,包含对象(object)、数组(array)、字符串(string)、数字(number)、布尔值(boolean)、null等数据类型。其中,对象由键值对组成,使用花括号{}包围;数组则是由方括号[]包围的一组值。每个值都可以是简单数据类型,也可以是复杂的数据结构。
一个简单的JSON对象形式如下:
{
"name": "JSON",
"array": ["value1", "value2", 3],
"boolean": true,
"null": null
}
(2)nlohmann::json简介
nlohmann/json(.hpp)是一个流行的C++库,用于处理JSON数据格式。它被设计为简单、灵活且功能强大,广泛用于C++项目中。
1)起源与发展
nlohmann/json的起源可以追溯到其创建者Niels Lohmann的个人需求。 Niels Lohmann在使用其它C++ JSON库时,发现这些库要么过于复杂、要么性能不佳、要么使用起来不够直观。因此,他决定自己开发一个满足这些需求的JSON库。经过一段时间的开发和优化,nlohmann/json.hpp逐渐成为了一个功能全面、性能卓越的JSON库。它支持C++11及更高版本的标准,充分利用了现代C++ 的特性,如范围for循环、结构化绑定等, 使得操作JSON数据变得更加简单和直观。随着其在 GitHub上的开源和发布,nlohmann/json.hpp迅速获得了广泛的关注和认可。大量的用户和贡献者加入了这个项目,为其提供了丰富的功能和稳定的性能。如今,nlohmann/json.hpp已经成为C++ 社区中非常受欢迎的JSON库之一。
2)特点与优势
nlohmann/json的特点包括:
- 单一头文件:nlohmann/json库仅需包含一个头文件,无需编译或安装步骤,便于集成和使用。
- 零外部依赖:库不依赖于其它库,简化了部署和分发。
- 异常安全:库支持异常处理,确保了在发生错误时能够安全地清理资源。
- 一致的接口:库提供了简洁的接口,使得JSON操作直观且容易记忆。
- 支持C++11特性:充分利用C++11及更高版本的特性,如std::move、std::initializer_list等。
- 良好的文档和社区支持:拥有详细的文档和活跃的社区,便于用户学习和问题解决。
与其它C++ JSON库相比,nlohmann/json.hpp有以下显著优势:
- 易用性:nlohmann/json.hpp提供了直观且易于使用的API,使得开发者能够快速地理解和使用它。与其它库相比,其减少了学习成本,提高了开发效率。
- 高性能:在解析和生成JSON数据方面,nlohmann/json.hpp表现出色。 它的性能优于许多其它C++ JSON库,使得在处理大量JSON数据时更加高效。
- 单文件库:nlohmann/json.hpp是一个单文件库,无需额外的链接或构建步骤。这使得它非常容易集成到任何C++项目中,无论项目大小如何。
3)下载安装
nlohmann/json库的下载安装步骤如下:
a)访问nlohmann/json的GitHub页面或者直接下载JSON库文件;
b)将下载的nlohmann/json.hpp文件拷贝到项目目录中;
c)确保项目编译器能够找到该文件。通常的做法是将其放在项目的include目录下,或者在编译器的包含路径中指定其位置;
d)在项目中包含该头文件并开始使用库提供的功能。
4)在C++中的应用
- 基本语法代码示例
//创建JSON对象
//可以使用nlohmann::json类来创建JSON对象,通过键值对的方式添加数据。
#include "nlohmann/json.hpp"
int main() {
nlohmann::json j;
j["name"] = "John Doe";
j["age"] = 30;
j["is_student"] = false;
return 0;
}
//解析JSON字符串
//nlohmann::json类还提供了从JSON字符串解析数据的功能。
int main() {
std::string json_str = R"({"name": "Jane Smith", "age": 25, "is_student": true})";
nlohmann::json j = nlohmann::json::parse(json_str);
std::cout << "Name: " << j["name"] << std::endl;
std::cout << "Age: " << j["age"] << std::endl;
std::cout << "Is Student: " << j["is_student"].get<bool>() << std::endl;
return 0;
}
//生成JSON字符串
//可以使用dump()方法将nlohmann::json对象转换为JSON字符串。
int main() {
nlohmann::json j;
j["name"] = "Alice";
j["hobbies"] = nlohmann::json::array({ "reading", "painting", "swimming" });
std::string json_str = j.dump(4); // 4表示缩进空格数
std::cout << json_str << std::endl;
return 0;
}
- 高级语法代码示例
//遍历JSON对象
nlohmann::json j = {
{"name", "Bob"},
{"age", 28},
{"address", {
{"street", "123 Main St"},
{"city", "New York"},
{"state", "NY"}
}}
//结构化绑定
for (const auto& [key, value] : j.items()) {
std::cout << "Key: " << key << ", Value: " << value << std::endl;
}
//迭代器遍历
for (auto it = j.begin(); it != j.end(); ++it) {
std::cout << "Key: " << it.key() << ", Value: " << it.value() << std::endl;
}
//遍历值
for (const auto& value : j) {
std::cout << "value: " << value<<std::endl;
}
//JSON数组操作
//nlohmann::json还支持JSON数组的操作,可以添加、删除和修改数组元素。
int main() {
nlohmann::json arr = nlohmann::json::array();
arr.push_back("Apple");
arr.push_back("Banana");
arr.push_back("Cherry");
arr[1] = "Blueberry"; // 修改数组中的元素
arr.pop_back(); // 删除数组中的最后一个元素
for (const auto& value : arr) {
std::cout << value << std::endl;
}
return 0;
}
序列化和反序列化
#include "nlohmann/json.hpp"
class TestA
{
public:
TestA(){}
TestA(int v1, string v2):i(v1),s(v2) {}
int i;
string s;
void to_json(nlohmann::json& j) const {
j = nlohmann::json{{"i", i}, {"s", s}};
}
void from_json(const nlohmann::json& j) {
i = j["i"];
s = j["s"];
}
//或者使用下面的宏来序列化和反序列化
//NLOHMANN_DEFINE_TYPE_INTRUSIVE(TestA, i, s)
};
void main()
{
std::string json_str = R"({
"i": 1,
"s": "str"
})";
json j1 = json::parse(json_str);
TestA B;
//反序列化
B.from_json(j1);
cout<<B.i<<B.s<<endl;
}
更多内容请看下回。