当前位置: 首页 > news >正文

C++开源库使用:nlohmann/json

1. 简介

这个库应该是最火的一个json解析的c++的开源库了吧!

可它是个模板库,我基本看不懂它啊!

不过学会怎么用就够了吧,

我用它主要目的是给我的avl写测试样例时,

可以直接从json文件进行读入测试样例。

我也似乎不是第一次用这个库了,之前也用过不过没写博客记录。

2. 构建

这个库提供了一个header-only的版本,

可以直接把single_include这个文件夹给放到头文件夹下。

不过我这里用的是cmake fetchcontent

# Typically you don't care so much for a third party library's tests to be
# run from your own project's 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 "")# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
# unintended consequences that will break the build.  It's 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);

你如果想直接读取内容,直接访问就好了。

如果想要转化,可以在后面跟get<T>()

std::vector<int> arr{ data["array"].get<std::vector<int>>()};

我主要是要用一下序列化反序列化这个功能,

就是把一个类或者对象给转化成一个json对象,最终写入到文件或者是读到内存中来。

一般的对象其实都不用你做这一步,主要是你自定义的类需要搞。

这个库提供了一个宏来帮助你来完成这个事情

比如下面

struct avl_test_case {avl_test_case() = default;avl_test_case(std::vector<int> &&v, std::vector< avl_cont_op > &&ops, std::vector<int> &&last_order_seqs):input{std::move(v)},op{std::move(ops)},expect_seq{std::move(last_order_seqs)}{}avl_test_case(const  std::vector<int> &v, const std::vector<avl_cont_op> &ops,const  std::vector<int> &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::vector<int> input{};std::vector< avl_cont_op > op{};std::vector<int> 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 {template<>struct adl_serializer<avl_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::vector<avl_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.get<avl_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

http://www.dtcms.com/a/403488.html

相关文章:

  • Appium笔记
  • 找人做彩票网站多少钱专业网站优化公司报价
  • 天津平台网站建设公司东莞市南城区
  • 【开题答辩全过程】以 Java医院就医平台系统为例,包含答辩的问题和答案
  • 11.路由器的接口及其相关知识(2025年9月25日)
  • C#调用基于python打包的税务申报期限解析器exe工具
  • 沧州市东光建设局 网站技术教程优化搜索引擎整站
  • Java线程安全:synchronized锁机制详解
  • 浅谈Linux内核的LRU算法作用和原理
  • 自己做网站 最好的软件下载win10一键优化
  • Vue3 + Ant Design Vue 实现表格无限滚动加载(自定义指令版)
  • Golang语言基础篇006_Golang流程控制
  • 襄樊网站网站建设网站建设中管理员登录的代码怎么写
  • 打工人日报#20250924
  • 网站的构思重庆建设工程造价信息
  • 【lua】luajit 命令行使用指南
  • 网站配置系统搭建一个网站需要多久
  • 绿联UGOS Pro九月更新,三端优化,影音相册再升级
  • JAVA学习-预科部分(路线、博客、预备基础)
  • 使用IDEA创建项目
  • Transformer - Multi-Head Attention(多头注意力)
  • 网站建设及安全管理花店网站模板
  • A股大盘数据-20250924分析
  • 双目深度相机--10.双目视觉的主要步骤讲解分析
  • 【双光相机配准】可见光与红外相机计算Homography
  • 建网站 几个链接PHP网站建设项目经验
  • 石家庄哪里能做门户网站的招商局网站建设方案
  • 南通网站关键词优化广铁建设集团门户网站
  • Code-First 与数据库迁移工具设计文档
  • VScode(Visual Studio Code)常用配置大全(持续更新)