文章目录
一、nlohmann/json
1、简介
1、类似python调用json库一样, 非常的方便和直观。 绑定STL。
2、内存占用优化和运行速度并不是非常关心。
那里有无数的JSON库,每个库甚至都有其存在的理由。我们有这些设计目标:
直观的语法。 在 Python 等语言中,JSON 感觉就像是一流的数据类型。我们使用了现代 C++ 的所有运算符魔术来在您的代码中实现相同的感觉。看看下面的例子,你就会明白我的意思。
微不足道的整合。 我们的整个代码由一个头文件组成json.hpp。就是这样。没有库,没有子项目,没有依赖项,没有复杂的构建系统。该类是用 C++11 编写的。总而言之,一切都不需要调整编译器标志或项目设置。
非常全面的测试。 我们的课程经过大量单元测试,涵盖了100%的代码,包括所有异常行为。此外,我们使用Valgrind和Clang Sanitizers检查了没有内存泄漏。Google OSS-Fuzz还针对所有解析器 24/7 运行模糊测试,迄今为止有效执行了数十亿次测试。为了保持高质量,该项目遵循核心基础设施倡议 (CII) 最佳实践。
其他方面对我们来说并不那么重要:
内存效率。 每个 JSON 对象都有一个指针(联合的最大大小)和一个枚举元素(1 个字节)的开销。默认泛化使用以下 C++ 数据类型:std::string字符串、int64_t数字、对象、数组和uint64_t布尔值。但是,您可以根据需要对通用类进行模板化。doublestd::mapstd::vectorboolbasic_json
速度。 当然有更快的 JSON 库。但是,如果您的目标是通过添加带有单个标头的 JSON 支持来加速您的开发,那么这个库就是您要走的路。如果您知道如何使用std::vectoror std::map,那么您已经准备好了。
2. cmake环境搭建
# 下载json代码
include(FetchContent)
FetchContent_Declare(
nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json
GIT_TAG v3.11.3
GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(nlohmann_json)
// 编译json代码,并链接到库
add_executable(json_guide main.cpp)
target_link_libraries(json_guide PRIVATE nlohmann_json::nlohmann_json)
二、 解析json文件 (反序列化)
1.1 从文件中读入json
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
// ...
std::ifstream f("example.json");
json data = json::parse(f);
1.2 字符串读入 (序列化)
// Using (raw) string literals and json::parse
json ex1 = json::parse(R"(
{
"pi": 3.141,
"happy": true
}
)");
1.3 从json对象中解析数据
- 解析普通数据
// strings
std::string s1 = "Hello, world!";
json js = s1;
auto s2 = js.template get<std::string>();
// NOT RECOMMENDED
std::string s3 = js;
std::string s4;
s4 = js;
// Booleans
bool b1 = true;
json jb = b1;
auto b2 = jb.template get<bool>();
// NOT RECOMMENDED
bool b3 = jb;
bool b4;
b4 = jb;
// numbers
int i = 42;
json jn = i;
auto f = jn.template get<double>();
// NOT RECOMMENDED
double f2 = jb;
double f3;
f3 = jb;
// etc.
- 枚举类型解析
该json库提供了一种特殊的直接从json文件中,解析出枚举类型值的方法。
- 将json
// create a JSON value
json j = R"({"compact": true, "schema": 0})"_json;
// serialize to BSON
std::vector<std::uint8_t> v_bson = json::to_bson(j);
1.4 解析json对象的属性
假设有一个 json
对象:
j["list"] = { 1, 0, 2 };
// 1. at获取
float pi = j.at("pi");
for(int i=0; i<3; i++)
std::cout << j.at("list").at(i) << std::endl;
json j;
j["name"] = p.name;
// 2. get获取
j["name"].get<std::string>(),
// 3. 判断j是否有这个属性
if (j.find("xxx") != j.end()) {
cout << j.at("xxx");
j["xxx"].get<std::string>();
}
// 4. 判断j是否有这个属性
if (j_obj.contains("data")) {
cout << j_obj.at("data") << endl;
j_obj["data"] = "999999";
} else {
cout << "no had" << endl;
}
// 5. 从json中读取数据
if (j_obj.contains("data")) {
cout << "------------" << endl;
cout << j_obj["data"].get<std::string>() << endl;
cout << "------------" << endl;
}
三. 导出都json文件
2.1 c++对象和Json字段映射
// create an empty structure (null)
json j;
// add a number that is stored as double (note the implicit conversion of j to an object)
j["pi"] = 3.141;
// add a Boolean that is stored as bool
j["happy"] = true;
// add a string that is stored as std::string
j["name"] = "Niels";
// add another null object by passing nullptr
j["nothing"] = nullptr;
// add an object inside the object
j["answer"]["everything"] = 42;
// add an array that is stored as std::vector (using an initializer list)
j["list"] = { 1, 0, 2 };
// add another object (using an initializer list of pairs)
j["object"] = { {"currency", "USD"}, {"value", 42.99} };
2.2 导入到文件
// read a JSON file
std::ifstream i("file.json");
json j;
i >> j;
// write prettified JSON to another file
std::ofstream o("pretty.json");
o << std::setw(4) << j << std::endl;
2.3 导出到string
// explicit conversion to string
std::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
// }
四、常用API
accept
, 查看是不是合法的json文本
// an invalid JSON text
auto invalid_text = R"(
{
"strings": ["extra", "comma", ]
}
)";
std::cout << std::boolalpha
<< json::accept(valid_text) << ' '
json::array()
新建一个json数组j.at()
demo 工程
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
#include <nlohmann/json.hpp>
using json = nlohmann::json;
void save_example_json_file(const std::string &filepath) {
json j;
j["name"] = "test";
}
json load_example(const std::string &filepath) {
ifstream f(filepath.c_str());
json data = json::parse(f);
return std::move(data);
}
int main(int argc, char const *argv[]) {
json j_obj =
load_example("/Users/chendongsheng/github/algo/src/json/test.json");
cout << j_obj.dump(4) << endl;
auto i = j_obj.find("persion_list");
if (i == j_obj.end()) {
cout << "it's end" << endl;
} else {
cout << i.key() << endl;
cout << i.value() << endl;
}
if (j_obj.contains("data")) {
// cout << j_obj.at("data") << endl;
cout << "------------" << endl;
cout << j_obj["data"].get<std::string>() << endl;
cout << "------------" << endl;
j_obj["data"] = "999999";
} else {
cout << "no had" << endl;
}
std::ofstream file("/Users/chendongsheng/github/algo/src/json/pretty.json");
file << j_obj << std::endl;
return 0;
}