最新网站制作,刚刚大连发生了大事,360免费建站软仵下载,网站关键词数量1. 简介
这个库应该是最火的一个json解析的c的开源库了吧#xff01;
可它是个模板库#xff0c;我基本看不懂它啊#xff01;
不过学会怎么用就够了吧#xff0c;
我用它主要目的是给我的avl写测试样例时#xff0c;
可以直接从json文件进行读入测试样例。
我也似乎…1. 简介
这个库应该是最火的一个json解析的c的开源库了吧
可它是个模板库我基本看不懂它啊
不过学会怎么用就够了吧
我用它主要目的是给我的avl写测试样例时
可以直接从json文件进行读入测试样例。
我也似乎不是第一次用这个库了之前也用过不过没写博客记录。
2. 构建
这个库提供了一个header-only的版本
可以直接把single_include这个文件夹给放到头文件夹下。
不过我这里用的是cmake 的fetchcontent
# Typically you dont care so much for a third party librarys tests to be
# run from your own projects code.
set(JSON_BuildTests OFF CACHE INTERNAL )# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
# set(JSON_Install OFF CACHE INTERNAL )# Dont use include(nlohmann_json/CMakeLists.txt) since that carries with it
# unintended consequences that will break the build. Its generally
# discouraged (although not necessarily well documented as such) to use
# include(...) for pulling in other CMake projects anyways.
add_subdirectory(nlohmann_json)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)3. 使用
这个库使用起来非常简单
如果要解析一个json文件,下面的代码就够了
#include fstream
#include nlohmann/json.hpp
using json nlohmann::json;// ...std::ifstream f(example.json);
json data json::parse(f);你如果想直接读取内容直接访问就好了。
如果想要转化可以在后面跟getT()
std::vectorint arr{ data[array].getstd::vectorint()};我主要是要用一下序列化反序列化这个功能
就是把一个类或者对象给转化成一个json对象最终写入到文件或者是读到内存中来。
一般的对象其实都不用你做这一步主要是你自定义的类需要搞。
这个库提供了一个宏来帮助你来完成这个事情
比如下面
struct avl_test_case {avl_test_case() default;avl_test_case(std::vectorint v, std::vector avl_cont_op ops, std::vectorint last_order_seqs):input{std::move(v)},op{std::move(ops)},expect_seq{std::move(last_order_seqs)}{}avl_test_case(const std::vectorint v, const std::vectoravl_cont_op ops,const std::vectorint expect): input{v}, op{ops},expect_seq{expect}{}bool isEqual(const avl_test_case tcase) {return tcase.expect_seq expect_seq tcase.input input tcase.op op;}std::vectorint input{};std::vector avl_cont_op op{};std::vectorint expect_seq{};};NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(avl_test_case, input, op, expect_seq)在生成json对象时属性名就是对应的成员变量名。
当然你也可以自定来定义序列化和反序列化的这个过程。
就像下面那样需要自己去实现to_json from_json这两个方法。
enum avl_op_tp {AVL_INSERT 0,AVL_DEL,AVL_FIND,AVL_NULL_OP
};struct avl_cont_op {bool operator(const avl_cont_op op1) const{return tp op1.tp cnt op1.cnt;}avl_op_tp tp{AVL_NULL_OP};uint32_t cnt{};
};namespace nlohmann {templatestruct adl_serializeravl_cont_op {static void to_json(json j, const avl_cont_op cont_op) {j json::object();j[tp] cont_op.tp;j[cnt] cont_op.cnt;}static void from_json(const json j, avl_cont_op cont_op) {j.at(tp).get_to(cont_op.tp);j.at(cnt).get_to(cont_op.cnt);}};
}修改json文件的话主要是拿到对应的json 数据注意一定是引用不然你的修改就不生效了。在修改完json数据之后还需要再写回到文件中去。
void AVLTestManager::load_data() {std::ifstream file(filename_);if (!file.good()) {// 文件不存在创建基本结构data_ nlohmann::json::object();data_[hello] world;data_[tests] nlohmann::json::array();} else {try {data_ nlohmann::json::parse(file);} catch (const nlohmann::json::parse_error e) {throw std::runtime_error(Failed to parse JSON file: std::string(e.what()));}}}// 保存数据到文件
void AVLTestManager::save_data() {std::ofstream file(filename_);if (!file.is_open()) {throw std::runtime_error(Failed to open file for writing: filename_);}file std::setw(4) data_ std::endl;
}再给一段代码吧我也只是会用了。不太理解这个模样库。
还有个问题是写入json文件时json文件的空白固定成4个了。
所以有时候有数组的对象会占据非常多的行暂时还没有解决这个
问题不过能跑就行。。。哈哈哈。
class AVLTestManager{
public:explicit AVLTestManager(const std::string filename):filename_{filename}{load_data();}bool addTestCase(const std::string suite_name, const avl_test_case test_case);bool removeTestSuite(const std::string suite_name);bool removeTestCase(const std::string suite_name, const avl_test_case test_case);bool removeTestCaseByIndex(const std::string suite_name, size_t idx);std::vectoravl_test_suite getAllTestSuites();private:void load_data();void save_data();nlohmann::json data_;std::string filename_;
};bool AVLTestManager::addTestCase(const std::string suiteName, const avl_test_case testCase) {auto testsArray data_[tests];bool suiteFound false;bool caseFound false;for (auto suite : testsArray) {if (suite[suite_name] suiteName) {suiteFound true;auto casesArray suite[cases];// 检查是否已存在相同的测试用例for (const auto existingCase : casesArray) {auto existingCaseObj existingCase.getavl_test_case();if (existingCaseObj.isEqual(testCase)) {caseFound true;break;}}if (!caseFound) {casesArray.push_back(testCase);save_data();return true;}break;}}if (!suiteFound) {// 创建新套件avl_test_suite newSuite;newSuite.suite_name suiteName;newSuite.cases.push_back(testCase);testsArray.push_back(newSuite);save_data();return true;}return false;
}
4. 参考
nlohmann/json