C++开源库使用:nlohmann/json - 指南

news/2025/10/22 19:48:32/文章来源:https://www.cnblogs.com/slgkaifa/p/19158821

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.mzph.cn/news/943682.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实用指南:JAVA学习-预科部分(路线、博客、预备基础)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【比赛记录】2025CSP+NOIP 冲刺模拟赛合集Ⅱ

2025CSP-S模拟赛65(HZOJ CSP-S模拟37)A B C D Sum Rank100 40 15 - 155 7/12HZOJ 上也有这场比赛,但我没看见。放过去大概是个 14/24 左右吧。 A. gcd&xor (gcdxor) 首先打表,发现对于所有合法的 \((x,y)\),都…

取证-windbg和dmp,以及文件分析基本流程

.dmp文件及Dump Flie,是一种内存快照文件 说到内存快照就不得不提一下文件类型 说明 常见用途.raw 原始磁盘映像文件(Raw Image),完整保存磁盘或内存的原始二进制数据。 虚拟机快照、数字取证、系统备份。.dmp 内存…

20232422 2025-2026-1 《网络与系统攻防技术》实验二实验报告

后门原理与实践 1.1实验内容 这次的实验主要练了几种获取主机操作权限和收集信息的方法。先是用netcat配合Linux的cron定时任务,还有socat搭配系统任务计划,分别搞到了主机的操作Shell,拿到了控制主机的入口。然后用…

羊驼二次免疫的六大风险:纳米抗体制备不可忽视的 “隐形陷阱”

随着纳米抗体在肿瘤治疗、病原体检测、工业酶固定化等领域的应用拓展,对羊驼免疫及 VHH 筛选的需求持续攀升。羊驼因饲养、运输、免疫成本显著高于小鼠、兔子,市场上逐渐出现 “二次免疫” 操作 —— 即利用已免疫过…

完整教程:C++项目:仿muduo库高并发服务器-------connection模块

完整教程:C++项目:仿muduo库高并发服务器-------connection模块pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "…

营销数字化专家要求

目录背景和价值高级营销数字化专家(整合营销)职位描述任职要求参考资料 背景和价值高级营销数字化专家(整合营销) 深圳市 | 产品及解决方案类 职位描述营销数字化转型规划:对整合营销端到端流程,KOL营销、社媒营…

深入解析:线性代数 SVD | 令人困扰的精度 1

深入解析:线性代数 SVD | 令人困扰的精度 1pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…

小程序反编译包的架构文件

common是逻辑的代码 pages 存放小程序的页面,路径等 app.js 也是小程序的脚本代码 app.json 配置文件

【最终章】-串口收发指令处理器-Verilog语法学习EP12 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

10.22 CSP-S模拟37/2025多校冲刺CSP模拟赛7 改题记录

10.22HZOJ 写在前面 ACCODERS+洛谷双重大凶然后又加了场模拟赛。怎么感觉每次大凶就会临时加模拟赛。。。然后就是连续第inf场模拟赛切不了T1。。。疑似失去了所有的力气与手段。然后T2以为是假做法拿了25pts沾沾自喜,…

完整教程:LeapMotion_Demo演示

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[题解]P11126 [ROIR 2024] 三等分的数组 (Day 2)

P11126 [ROIR 2024] 三等分的数组 (Day 2) 考虑到数的选取与输入顺序无关,我们将数丢到桶里,记 \(c_x\) 为 \(x\) 出现的次数。 那么我们取出三元组的过程可以描述为下面二者之一:选取 \(c\) 中的一个位置,将其减去…

Acrobat Pro DC 2025下载及破解安装教程,附永久免费免激活中文版Acrobat Pro DC安装包(稳定版)

一、Acrobat Pro DC 2025软件下载[软件名称]: Acrobat Pro DC 2025(稳定版)[软件大小]: 1.63GB[安装环境]:Win 10及以上系统[下载链接]: (建议手机保存后到电脑端打开,下载解压无需任何密码)夸克:https://pan.qua…

VSLAM 十四讲--阅读中知识点记录

1. 前言砚上三五笔,落墨鹧鸪啼本文用于记录:VSLAM相关。 PS:笔者梦到哪里写哪里,毫无逻辑可言。。。 如有不对,欢迎评论区指正! 2. 正文 2.1 slamsimultaneous location and mapping 同步定位和建图相机:单目相…

20232307 2025-2026-1 《网络与系统攻防技术》实验二实验报告

20232307 2025-2026-1 《网络与系统攻防技术》实验二实验报告 1. 实验内容 相关知识:后门就是不经过正常认证流程而访问系统的通道。后门类型:编译器留后门、操作系统留后门、应用程序中留后门、还有潜伏于操作系统中…

Fiddler Script语句整理

请求函数: static function OnBeforeRequest(oSession:Sessiop){}响应函数: staticfunction OnBeforeResponse(oSession:Session){}修改样式语句:if (oSession.host.indexOf("mosoteach.cn") > -1) { …

微服务正在悄然消亡:这是一件美好的事

最近在做的事情正好需要系统地研究微服务与单体架构的取舍与演进。读到这篇文章,许多观点直击痛点、非常启发,于是我顺手把它翻译出来,分享给大家,也希望能给同样在复杂性与效率之间权衡的团队一些参考。 微服务正…

数据库学习篇(持续更新中)

在日常的开发中,常常会因为业务的复杂而编写复杂的数据库脚本。本篇记录博主在实际使用中的各种脚本及函数:人一旦有了梦想,怎么活都是有灵魂的!