在 C++ 中优雅地处理 JSON:nlohmann/json 库实践指南

news/2025/1/8 18:28:27/文章来源:https://www.cnblogs.com/linxmouse/p/18658022

JSON (JavaScript Object Notation) 作为一种轻量级的数据交换格式,在现代软件开发中扮演着重要角色。在 C++ 开发中,nlohmann/json 库因其易用性和灵活性而广受欢迎。本文将通过实例介绍如何使用这个强大的库进行 JSON 数据的序列化和反序列化操作。

环境准备

首先,我们需要配置项目环境。这里使用 CMake 作为构建系统:

cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
project("nlohmann_json_test" CXX)find_package(nlohmann_json CONFIG REQUIRED)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)add_executable(nlohmann_json_test nlohmann_json_test.cpp)
target_link_libraries(nlohmann_json_test PRIVATE nlohmann_json::nlohmann_json)

数据结构定义

在示例中,我们定义了三个主要的数据结构:

struct Address {std::string street;std::string number;std::string postcode;NLOHMANN_DEFINE_TYPE_INTRUSIVE(Address, street, number, postcode);
};struct Person {std::string name;int age;std::vector<Address> addresses;NLOHMANN_DEFINE_TYPE_INTRUSIVE(Person, name, age, addresses);
};struct ApiResult {bool success;std::string message;json data;NLOHMANN_DEFINE_TYPE_INTRUSIVE(ApiResult, success, message, data);
};

这里的关键是使用 NLOHMANN_DEFINE_TYPE_INTRUSIVE 宏,它自动为我们的结构体生成序列化和反序列化的代码。这大大简化了 JSON 转换过程,无需手动编写转换逻辑。

JSON 序列化示例

让我们看看如何将 C++ 对象序列化为 JSON:

Person person = {"John Doe",20,{{"Main St", "123", "12345"},{"Second St", "456", "67890"}}
};// 序列化为 JSON
json j = person;
std::cout << j.dump(4) << std::endl;

序列化结果:

{"addresses": [{"number": "123","postcode": "12345","street": "Main St"},{"number": "456","postcode": "67890","street": "Second St"}],"age": 20,"name": "John Doe"
}

JSON 反序列化示例

同样简单,我们可以将 JSON 字符串反序列化为 C++ 对象:

json j2 = R"({"name": "Jane Doe","age": 25,"addresses":[{"street":"jiangxia","number":"258","postcode":"54321"},{"street":"wuchang","number":"369","postcode":"12345"}]}
)"_json;Person person2;
j2.get_to(person2);

API 响应封装示例

在实际开发中,我们经常需要处理 API 响应。这里展示了如何使用 ApiResult 结构体封装不同类型的响应:

// 成功响应,携带数据
ApiResult ar1;
ar1.success = true;
ar1.message = "success";
ar1.data = person;
json jar1 = ar1;// 错误响应
ApiResult ar2;
ar2.success = false;
ar2.message = "A fatal error has occurred";
ar2.data = nullptr;
json jar2 = ar2;

这将产生如下 JSON 输出:

成功响应:

{"data": {"addresses": [...],"age": 20,"name": "John Doe"},"message": "success","success": true
}

错误响应:

{"data": null,"message": "A fatal error has occurred","success": false
}

主要特点和优势

  1. 简单直观的 API:通过 NLOHMANN_DEFINE_TYPE_INTRUSIVE 宏,可以轻松实现序列化和反序列化。
  2. 类型安全:编译时类型检查,避免运行时错误。
  3. 灵活的数据处理:支持复杂的嵌套结构和各种数据类型。
  4. 现代 C++ 特性支持:与 C++11 及以上版本完全兼容。
  5. 错误处理:提供清晰的错误信息和异常处理机制。

注意事项

  1. 使用 NLOHMANN_DEFINE_TYPE_INTRUSIVE 时,需要确保所有成员变量都是可序列化的。
  2. 在处理大型 JSON 数据时,要注意内存使用。
  3. 对于非字符串类型的键,需要特别处理。
  4. C++20 提供了更简洁的结构体初始化语法,但要注意编译器支持情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/865428.html

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

相关文章

AutoGen入门-让两个AI自行聊天完成任务

AutoGen介绍 AutoGen 是一个开源编程框架,用于构建 AI 代理并促进多个代理之间的合作以解决问题。AutoGen 旨在提供一个易于使用和灵活的框架,以加速代理型 AI 的开发和研究,就像 PyTorch 之于深度学习。它提供了诸如代理之间可以对话、LLM 和工具使用支持、自主和人机协作工…

Centos7 安装redis教程

步骤一:安装gcc依赖检查gcc是否已经安装,命令:gcc -v,出现下图说明已经安装由于 redis 是用 C 语言开发,安装之前必先确认是否安装 gcc 环境(gcc -v),如果没有安装,执行以下命令进行安装yum install -y gcc步骤二:下载redis安装包 https://download.redis.io/relea…

【编码】如何实现一套自定义网络协议?

前言 下文介绍的自定义协议仅作为学习示例,纯粹是玩具项目,没有实际可用性。无需过度关注和讨论其合理性 进行通信的双方是谁? 常见的模型 客户端-服务器,例如HTTP协议,浏览器<=>Web服务器。 中转站模型,如MQTT协议,应用服务<=>中转站<=>硬件客户端 对…

记录一个使用VsCode来ssh的问题(已经打开了ssh的一个文件夹路径,怎么新开一个文件夹路径)

一、操作 使用快捷键 Ctrl+Shift+P(Windows) 或 Cmd+Shift+P (Mac)打开 命令面板 然后输入: File:Open Folder之后就可以选项新的路径打开了。。。没想到我被这个卡了好久,有点无语。

Postman配置接口挡板

0、首先需要在postman上注册并登录账号(登录前最好先备份已有的报文) 如果你在登录后发现历史存储的报文不见了,不要担心,在退出登录后将会重新显示出来。你可以将之前备份的报文导入到登录后的workspace中使用1、进入Workspace,新建Collection 2、找到新建的collection…

vue3新建项目的DevTools Settings

找到vite.config.js 注释掉这两行就消失了

Linux文件系统的安全保障---Overlayroot!

`overlayroot` 是一种使用 OverlayFS 实现的功能,可将根文件系统挂载为只读,并通过一个临时的写层实现对文件系统的修改。这种方法非常适合嵌入式设备或需要保持系统文件完整性和安全性的场景。下文以 RK3568 平台为例,介绍制作 overlayroot 的详细步骤。 ​ 1. 制作精简文件…

DirectX 修复工具 V4.3 绿色增强版:完美解决 DirectX 和 C++ 问题,修复 0xc000007b 错误

介绍 DirectX 修复工具 V4.3 是一款高效的系统修复工具,专为解决 系统异常 和 C++ 运行库 问题而设计,尤其对解决 0xc000007b 错误有着极高的修复率。本工具支持对所有版本的 DirectX 进行修复,并在增强版中新增了对 C++ 运行库问题的修复,提供了一个全面且可靠的解决方案。…

用DevEco Studio模拟器这些能力 没真机也能高效调测鸿蒙原生应用

随着鸿蒙生态的快速发展,越来越多的开发者投身于鸿蒙原生应用的开发中。然而,在实际开发中,真机设备短缺、调测场景复杂等问题常困扰着开发者。为解决这些问题,华为在DevEco Studio上为开发者提供了模拟器(Emulator)功能,帮助开发者在真机匮乏或无真机时,高效且低成本地…

renben-openstack-使用操作

管理员操作 (1)上传一个qcow2格式的centos7镜像 (2)管理员------>云主机类型------>创建云主机类型名称:Centos7VCPU数量:1内存: 1024根磁盘: 10G其他的默认点击创建云主机类型即可界面会显示如下创建公网络 (1)创建公网管理员------>网络------>创建网络…

防护用具穿戴智能监测摄像机

防护用具穿戴智能监测摄像机在现代安全管理中扮演着越来越重要的角色。这些先进设备不仅仅是简单的监视工具,更是通过整合高级技术来提升工作效率和安全性,特别是在复杂环境和危险作业场所的应用日益广泛。防护用具穿戴智能监测摄像机不仅仅是一种安全设备,更是提升工作场所…

场景题:假设有40亿QQ号,但只有1G内存,如何实现去重?

当数据量比较大时,使用常规的方式来判重就不行了。例如,使用 MySQL 数据库判重,或使用 List.contains() 或 Set.contains() 判重就不行了,因为数据量太大会导致内存放不下,或查询速度太慢等问题。 1.空间占用量预测 正常情况下,如果将 40 亿 QQ 号存储在 Java 中的 int 类…