nlohmann/json是一个用于解析JSON的开源 C++ 库,口碑一流,使用非常方便直观,是很多 C++ 程序员的首选。
通过github可以获取到源码。参考其README可以快速了解使用方法。
nlohmman/json的使用也非常简单,将include/nlohmann/json文件夹拷贝到工程中,添加路径即可使用其头文件
1 |
构建JSON对象
创建一个如下的格式JSON对象:
1 | { |
使用以下方式:
1 | nlohmman::json j; |
在进行如上方式构造 JSON 对象时,你并不需要告诉编译器你要使用哪种类型,nlohmann 会自动进行隐式转换。对应如下:
string序列化和反序列化
反序列化:从std::string恢复JSON对象。
1
2
3
4
5
6
7
8
9
10
11
12
13// create object from string literal
json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
// or even nicer with a raw string literal
auto j2 = R"(
{
"happy": true,
"pi": 3.141
}
)"_json;
// parse explicitly
auto j3 = json::parse(R"({"happy": true, "pi": 3.141})");序列化:Json转std::string
1
2
3
4
5
6
7
8
9std::string s = j.dump(); // {\"happy\":true,\"pi\":3.141}
// serialization with pretty printing
// pass in the amount of spaces to indent
std::cout << j.dump(4) << std::endl;
// {
// "happy": true,
// "pi": 3.141
// }注意区分序列化和设置std::string value:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// store a string in a JSON value
json j_string = "this is a string";
// retrieve the string value
auto cpp_string = j_string.get<std::string>();
// retrieve the string value (alternative when an variable already exists)
std::string cpp_string2;
j_string.get_to(cpp_string2);
// retrieve the serialized value (explicit JSON serialization)
std::string serialized_string = j_string.dump();
// output of original string
std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << '\n';
// output of serialized value
std::cout << j_string << " == " << serialized_string << std::endl;dump()返回 JSON 对象中存储的原始 string 值。
该库仅支持UTF-8. 如果存储其他的编码数据,当调用dump()时,可能抛出异常。Note the library only supports UTF-8. When you store strings with different encodings in the library, calling dump() may throw an exception unless json::error_handler_t::replace or json::error_handler_t::ignore are used as error handlers.
stream和json的转换
1
2
3
4
5
6
7
8
9// deserialize from standard input
json j;
std::cin >> j;
// serialize to standard output
std::cout << j;
// the setw manipulator was overloaded to set the indentation for pretty printing
std::cout << std::setw(4) << j << std::endl;json和文件的读写
1
2
3
4
5
6
7
8
9
10
11
12
13// read a JSON file
std::ifstream file("file.json");
if (!file.is_open()) {
return;
}
json j;
file >> j;
file.close();
// write prettified JSON to another file
std::ofstream file("pretty.json");
file << std::setw(4) << j << std::endl;std::vector<>或者std::liststd::uint16_t
1
2
3
4
5
6std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
json j = json::parse(v.begin(), v.end());
# You may leave the iterators for the range [begin, end):
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
json j = json::parse(v);自定义数据结构struct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25namespace ns {
// a simple struct to model a person
struct person {
std::string name;
std::string address;
int age;
};
}
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
// convert to JSON: copy each value into the JSON object
json j;
j["name"] = p.name;
j["address"] = p.address;
j["age"] = p.age;
// ...
// convert from JSON: copy each value from the JSON object
ns::person p {
j["name"].get<std::string>(),
j["address"].get<std::string>(),
j["age"].get<int>()
};更方便的方式:to_json()和from_json():
1
2
3
4
5
6
7
8
9
10
11
12
13using json = nlohmann::json;
namespace ns {
void to_json(json& j, const person& p) {
j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
}
void from_json(const json& j, person& p) {
j.at("name").get_to(p.name);
j.at("address").get_to(p.address);
j.at("age").get_to(p.age);
}
} // namespace ns如果key”name”不存在,会抛出异常,可以使用以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24# 方式1:catch异常
void from_json(const json& j, person& p) {
try {
j.at("name").get_to(p.name);
j.at("address").get_to(p.address);
j.at("age").get_to(p.age);
} catch (const std::exception &e)
{
std::cout << e.what() << std::endl;
}
}
# 方式2:优先判断
void from_json(const json& j, person& p) {
if (j.contains("name")) {
j.at("name").get_to(p.name);
}
if (j.contains("address")) {
j.at("address").get_to(p.address);
}
if (j.contains("age")) {
j.at("age").get_to(p.age);
}
}有了以上实现,可以如下使用:
1
2
3
4ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
json j = p;
ns::person p1 = j.get<ns::person>();class也可以使用to_json()和from_json()
1 |
|
如果类成员是private:
1 | class Person { |
Binary formats(BSON…)
二进制数据的转换
1 | // create a JSON value |
1 |
1 |