nlohmann/json 是一个用于解析 JSON 的开源 C++库,口碑一流,无需额外安装其他第三方库,还支持单个头文件模式,使用起来非常方便直观。

1. 编译

从官网https://github.com/nlohmann/json的 Release 页面下载单个json.hpp即可直接使用,无需单独编译。

2. 使用示例

下面以示例的方式罗列 nlohmann/json 库的基本使用方法。

2.1 生成 JSON

方式 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
using json = nlohmann::json;

json j;
j["pi"] = 3.141;
j["happy"] = true;
j["name"] = "Niels";
j["nothing"] = nullptr;
j["answer"]["everything"] = 42;
j["list"] = { 1, 0, 2 };
j["object"] = { {"currency", "USD"}, {"value", 42.99} };

// 转成字符串
std::string strJSON = j.dump(2); // 2个空格的缩进

std::cout << strJSON;
return 0;
}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"answer": {
"everything": 42
},
"happy": true,
"list": [1, 0, 2],
"name": "Niels",
"nothing": null,
"object": {
"currency": "USD",
"value": 42.99
},
"pi": 3.141
}

方式 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
using json = nlohmann::json;
json j = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {{"everything", 42}}},
{"list", {1, 0, 2}},
{"object", {{"currency", "USD"}, {"value", 42.99}}}
};

// 转成字符串
std::string strJSON = j.dump(2);

std::cout << strJSON;
return 0;
}

输出内容与方式 1 一样。

方式 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main()
{
using json = nlohmann::json;

json j;
j["pi"] = 3.141;
j["happy"] = true;
j["name"] = "Niels";
j["nothing"] = nullptr;

json j_answer;
j_answer["everything"] = 42;

j["answer"] = j_answer;

json j_list = json::array();
j_list.push_back(1);
j_list.push_back(0);
j_list.push_back(2);

j["list"] = j_list;

json j_object;
j_object["currency"] = "USD";
j_object["value"] = 42.99;

j["object"] = j_object;

// 转成字符串
std::string strJSON = j.dump(2);

std::cout << strJSON;
return 0;
}

输出内容与方式 1 一样。

2.2 解析 JSON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
int main()
{
using json = nlohmann::json;

std::string strJSON = u8R"(
{
"answer": {
"everything": 42
},
"happy": true,
"list": [
1,
0,
2
],
"name": "Niels",
"nothing": null,
"object": {
"currency": "USD",
"value": 42.99
},
"pi": 3.141
}
)";

auto jsonObj = json::parse(strJSON);
std::cout << jsonObj["pi"].get<float>() << std::endl; // 3.141
std::cout << jsonObj["pi"].get<double>() << std::endl; // 3.141
std::cout << std::boolalpha << jsonObj["happy"].get<bool>() << std::endl; // true
std::cout << jsonObj["name"].get<std::string>() << std::endl; // Niels
assert(jsonObj["nothing"] == nullptr);
std::cout << jsonObj["answer"]["everything"].get<int>() << std::endl; // 42
std::cout << jsonObj["list"].size() << std::endl; // 3
std::cout << jsonObj["list"][0].get<int>() << std::endl; // 1
std::cout << jsonObj["list"][1].get<int>() << std::endl; // 0
std::cout << jsonObj["list"][2].get<int>() << std::endl; // 2
std::cout << jsonObj["object"]["currency"].get<std::string>() << std::endl; // USD
std::cout << jsonObj["object"]["value"].get<float>() << std::endl; // 42.99

// 依次输出:
// 1
// 0
// 2
for (json::iterator it = jsonObj["list"].begin(); it != jsonObj["list"].end(); ++it) {
std::cout << *it << std::endl;
}

return 0;
}

3. 异常处理

当解析和生成 JSON 出错时,nlohmann/json 会抛出异常,因此在解析和生成 JSON 时,需要进行异常捕获。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
using json = nlohmann::json;

std::string strJSON = u8R"(
{
"pi": 3.141
}
)";

try {
auto jsonObj = json::parse(strJSON);
std::cout << jsonObj["ppp"].get<float>() << std::endl;
}
catch (std::exception& e) {
std::cout << e.what() << std::endl;
}

return 0;
}

4. 判断成员是否存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{
using json = nlohmann::json;

std::string strJSON = u8R"(
{
"pi": 3.141
}
)";

auto jsonObj = json::parse(strJSON);
std::cout << std::boolalpha << jsonObj.contains("pi") << std::endl; // true
std::cout << std::boolalpha << jsonObj.contains("ppp") << std::endl; // false

return 0;
}