1,什么是 nlohman::json
1.1,下载地址
git repo: GitHub - nlohmann/json: JSON for Modern C++
1.2,基本介绍
nlohmann是一个C++的JSON库,它提供了方便的方式来解析、生成和操作JSON数据。该库由nlohmann编写,是一个开源项目,被广泛应用于C++开发中。
nlohmann库提供了简单易用的API,可以轻松地将JSON数据解析为C++对象,或者将C++对象序列化为JSON数据。它支持各种数据类型,包括字符串、数字、布尔值、数组和对象等。我们可以使用简洁的语法来访问和操作JSON数据,使得编写JSON处理代码变得更加简单和高效。
除了基本的JSON解析和生成功能,nlohmann库还提供了一些高级功能,如JSON合并、JSON差异比较、JSON数据查询等。这些功能可以帮助我们更方便地处理复杂的JSON数据,提高代码的可维护性和可读性。
2,具体解析示例
2.1,组成 json 串示例1
#include <iostream> // 包含标准输入输出流的头文件
#include <nlohmann/json.hpp> // 包含nlohmann/json库的头文件
using ordered_json = nlohmann::ordered_json; // 定义别名ordered_json,映射到nlohmann库中的ordered_json类
int main()
{
ordered_json j; // 创建ordered_json类型的变量j
j["one"] = 1; // 向j中添加键值对"one":1
j["two"] = 2; // 向j中添加键值对"two":2
j["three"] = 3; // 向j中添加键值对"three":3
std::cout << j.dump(2) << '\n'; // 将JSON对象转换为字符串并打印输出,缩进为2个空格
}
这是主函数的定义,程序的入口点。
首先创建了一个ordered_json
类型的变量j
,然后向其添加了三个键值对,分别对应"one"、"two"和"three"这三个键,并将它们的值设置为1、2和3。
最后,通过调用j.dump(2)
方法将JSON对象转换为字符串,并以格式化的方式打印输出到控制台。这里的参数2
指定了缩进的空格数为2个空格。
运行结果:
{
"one": 1,
"two": 2,
"three": 3
}
2.2,组成 json 串示例2
#include <iostream> // 包含标准输入输出流的头文件
#include <nlohmann/json.hpp> // 包含nlohmann/json库的头文件
// 定义一个输出函数,用于打印字典内容
template<typename Map>
void output(const char* prefix, const Map& m)
{
std::cout << prefix << " = { ";
for (auto& element : m)
{
std::cout << element.first << ":" << element.second << ' ';
}
std::cout << "}" << std::endl;
}
int main()
{
// 创建并填充两个字典
nlohmann::ordered_map<std::string, std::string> m_ordered; // 有序字典,按键顺序排序
m_ordered["one"] = "eins";
m_ordered["two"] = "zwei";
m_ordered["three"] = "drei";
std::map<std::string, std::string> m_std;// 普通字典,按键顺序排序,但不如有序字典稳定
m_std["one"] = "eins";
m_std["two"] = "zwei";
m_std["three"] = "drei";
// 输出:m_ordered按插入顺序排序,m_std按键排序
output("m_ordered", m_ordered);
output("m_std", m_std);
// 删除并重新添加"one"键
m_ordered.erase("one"); // 从有序字典中移除键值对
m_ordered["one"] = "eins"; // 重新添加键值对到有序字典的末尾(因为之前已经删除)
m_std.erase("one"); // 从普通字典中移除键值对
m_std["one"] = "eins"; // 重新添加键值对到普通字典的末尾(因为之前已经删除)
// 输出:m_ordered显示新添加的键在末尾;m_std仍然是按键排序的
output("m_ordered", m_ordered);
output("m_std", m_std);
}
运行结果:
m_ordered = { one:eins two:zwei three:drei }
m_std = { one:eins three:drei two:zwei }
m_ordered = { two:zwei three:drei one:eins }
m_std = { one:eins three:drei two:zwei }
2.3,解析 json 串示例1
#include <iostream> // 包含标准输入输出流的头文件
#include <nlohmann/json.hpp> // 包含nlohmann/json库的头文件
using json = nlohmann::json; // 使用nlohmann::json类的别名json
using namespace nlohmann::literals; // 使用nlohmann字面量命名空间
int main()
{
// 创建一个包含不同类型条目的JSON对象
json j =
{
{"integer", 1}, // integer类型的键值对,值为1
{"floating", 42.23}, // floating类型的键值对,值为42.23
{"string", "hello world"}, // string类型的键值对,值为"hello world"
{"boolean", true}, // boolean类型的键值对,值为true
{"object", {{"key1", 1}, {"key2", 2}}}, // object类型的键值对,内部为一个包含两个元素的数组,元素分别为1和2
{"array", {1, 2, 3}} // array类型的键值对,内部为一个包含三个元素的数组,元素分别为1、2、3
};
// 访问存在的值
int v_integer = j.value("/integer"_json_pointer, 0); // 获取整数类型的值,如果不存在则默认为0
double v_floating = j.value("/floating"_json_pointer, 47.11); // 获取浮点数类型的值,如果不存在则默认为47.11
// 访问不存在的值并依赖默认值
std::string v_string = j.value("/nonexisting"_json_pointer, "oops"); // 获取字符串类型的值,如果不存在则默认为"oops"
bool v_boolean = j.value("/nonexisting"_json_pointer, false); // 获取布尔类型的值,如果不存在则默认为false
// 输出值
std::cout << std::boolalpha << v_integer << " " << v_floating
<< " " << v_string << " " << v_boolean << "\n"; // 打印出获取到的值,其中v_integer和v_boolean会以文本形式(true/false)输出,而v_floating会以科学计数法输出,v_string会原样输出
}
运行结果:
1 42.23 oops false
2.4,解析 json 串示例2
#include <iostream> // 引入标准输入输出流头文件
#include <unordered_map> // 引入无序映射容器头文件
#include <nlohmann/json.hpp> // 引入nlohmann JSON库头文件
using json = nlohmann::json; // 使用nlohmann::json类的别名json
using namespace nlohmann::literals; // 使用nlohmann字面量命名空间
int main()
{
// 创建一个包含不同类型条目的JSON值
json json_types =
{
{"boolean", true}, // boolean类型的键值对,值为true
{
"number", { // number类型的键值对,内部为一个对象,包含两个属性:integer和floating-point
{"integer", 42}, // integer类型的键值对,值为42
{"floating-point", 17.23} // floating-point类型的键值对,值为17.23
}
},
{"string", "Hello, world!"}, // string类型的键值对,值为"Hello, world!"
{"array", {1, 2, 3, 4, 5}}, // array类型的键值对,内部为一个数组,包含五个元素:1、2、3、4、5
{"null", nullptr} // null类型的键值对,值为nullptr(空指针)
};
bool v1;
int v2;
short v3;
float v4;
int v5;
std::string v6;
std::vector<short> v7;
std::unordered_map<std::string, json> v8;
// 使用显式转换将JSON值转换为相应的变量类型
json_types["boolean"].get_to(v1); // 将布尔值转换为布尔变量v1
json_types["number"]["integer"].get_to(v2); // 将整数值转换为整数变量v2和v3(这里存在重复赋值的问题)
json_types["number"]["integer"].get_to(v3); // 将整数值转换为整数变量v3(这里存在重复赋值的问题)
json_types["number"]["floating-point"].get_to(v4); // 将浮点数值转换为浮点数变量v4和v5(这里存在重复赋值的问题)
json_types["number"]["floating-point"].get_to(v5); // 将浮点数值转换为浮点数变量v5(这里存在重复赋值的问题)
json_types["string"].get_to(v6); // 将字符串值转换为字符串变量v6
json_types["array"].get_to(v7); // 将数组值转换为向量变量v7(这里存在重复赋值的问题)
json_types.get_to(v8); // 将整个JSON对象转换为无序映射变量v8(这里也存在重复赋值的问题)
// 打印转换结果
std::cout << v1 << '\n'; // 打印布尔变量v1的值(true)
std::cout << v2 << ' ' << v3 << '\n'; // 打印重复赋值的整数变量v2和v3的值(42)和(42)
std::cout << v4 << ' ' << v5 << '\n'; // 打印重复赋值的浮点数变量v4和v5的值(17.23)和(17.23)
std::cout << v6 << '\n'; // 打印字符串变量v6的值(Hello, world!)
for (auto i : v7) { // 遍历向量变量v7并打印每个元素(这里存在重复赋值的问题)
std::cout << i << ' ';
}
std::cout << "\n\n";
for (auto i : v8) { // 遍历无序映射变量v8并打印键值对(这里存在重复赋值的问题)
std::cout << i.first << ": " << i.second << '\n';
}
}
运行结果:
1
42 42
17.23 17
Hello, world!
1 2 3 4 5
string: "Hello, world!"
number: {"floating-point":17.23,"integer":42}
null: null
boolean: true
array: [1,2,3,4,5]
2.5,解析 json 串示例3
complex.json
{
"employees": [
{
"firstName": "John",
"lastName": "Doe",
"age": 30,
"position": "Manager"
},
{
"firstName": "Jane",
"lastName": "Smith",
"age": 25,
"position": "Developer"
}
],
"projects": {
"Project X": {
"start_date": "2023-01-01",
"end_date": "2023-12-31",
"team_members": ["John Doe", "Jane Smith"]
},
"Project Y": {
"start_date": "2024-01-01",
"end_date": "2024-12-31",
"team_members": ["Jane Smith"]
}
}
}
#include <iostream> // 引入标准输入输出流头文件
#include <fstream>
#include <nlohmann/json.hpp> // 引入nlohmann JSON库头文件
using json = nlohmann::json; // 使用nlohmann::json类的别名json
int main()
{
std::ifstream file("complex.json");
json data;
file >> data;
std::cout << "Employees:" << std::endl;
for (const auto& employee : data["employees"]) {
std::cout << employee["firstName"] << " " << employee["lastName"] << ", age: " << employee["age"] << ", position: " << employee["position"] << std::endl;
}
std::cout << "Projects:" << std::endl;
for (const auto& project : data["projects"]) {
std::cout << project.first << ":" << std::endl;
std::cout << " Start date: " << project.second["start_date"] << std::endl;
std::cout << " End date: " << project.second["end_date"] << std::endl;
std::cout << " Team members: ";
for (const auto& member : project.second["team_members"]) {
std::cout << member << " ";
}
std::cout << std::endl;
}
return 0;
}
运行结果:
Employees:
John Doe, age: 30, position: Manager
Jane Smith, age: 25, position: Developer
Projects:
Project X:
Start date: 2023-01-01
End date: 2023-12-31
Team members: John Doe Jane Smith
Project Y:
Start date: 2024-01-01
End date: 2024-12-31
Team members: Jane Smith