C++ 中的 JSON 序列化和反序列化:结构体与枚举类型的处理

在 C++ 编程中,处理 JSON 数据是一项常见任务,特别是在需要与其他系统或前端进行数据交换时。nlohmann::json 库是一个功能强大且易于使用的 JSON 库,它允许我们轻松地在 C++ 中进行 JSON 数据的序列化和反序列化。本文将详细介绍如何使用 nlohmann::json 库对结构体和枚举类型进行序列化和反序列化。

一、结构体的 JSON 序列化和反序列化
1. 序列化方法 to_json

要将结构体转换为 JSON 对象,我们需要定义一个 to_json 函数。这个函数接收一个 nlohmann::json 引用和一个结构体实例,并将结构体的字段填充到 JSON 对象中。

inline void to_json(nlohmann::json &j, const YourStruct &p)
{j = nlohmann::json{{"field1", p.field1},{"field2", p.field2},// 添加其他字段};
}

在这个例子中,YourStruct 是一个自定义的结构体,field1field2 是它的字段。通过 to_json 函数,我们可以将 YourStruct 实例转换为 JSON 对象。

2. 反序列化方法 from_json

要从 JSON 对象中提取数据并填充到结构体中,我们需要定义一个 from_json 函数。这个函数同样接收一个 nlohmann::json 引用和一个结构体引用,并从 JSON 对象中提取数据并赋值给结构体的字段。

inline void from_json(const nlohmann::json &j, YourStruct &p)
{try {j.at("field1").get_to(p.field1);j.at("field2").get_to(p.field2);// 添加其他字段} catch (const nlohmann::json::exception& e) {// 处理解析错误,例如设置默认值或标记错误p.field1 = default_value1;p.field2 = default_value2;// 或者抛出异常// throw std::runtime_error("Failed to parse JSON: " + std::string(e.what()));}
}

在这个例子中,我们使用 try-catch 块来捕获可能的异常,例如 JSON 对象中缺少某个键。如果捕获到异常,我们可以选择设置默认值或抛出异常。

二、枚举类型的 JSON 序列化和反序列化

处理枚举类型的 JSON 序列化和反序列化时,我们可以使用 NLOHMANN_JSON_SERIALIZE_ENUM 宏来简化工作。

enum class YourEnum {Value1,Value2,// 添加其他枚举值
};NLOHMANN_JSON_SERIALIZE_ENUM(YourEnum,{ { YourEnum::Value1, "Value1" },{ YourEnum::Value2, "Value2" },// 添加其他枚举值})

在这个例子中,我们定义了一个枚举类型 YourEnum,并使用 NLOHMANN_JSON_SERIALIZE_ENUM 宏来定义枚举值的字符串表示形式。这样,YourEnum::Value1 将被序列化为字符串 "Value1",反之亦然。

三、示例代码

假设我们有两个结构体 RobotMsgRtdeRecipe,以及两个枚举类型 RuntimeStateRobotModeType。以下是完整的示例代码:

#include <nlohmann/json.hpp>
#include <vector>
#include <string>
#include <stdexcept>// 引入 JSON 库命名空间
using json = nlohmann::json;// 枚举类型定义及序列化
enum class RuntimeState {Running,Retracting,Pausing,Paused,Stopping,Stopped,Aborting
};NLOHMANN_JSON_SERIALIZE_ENUM(RuntimeState,{ { RuntimeState::Running, "Running" },{ RuntimeState::Retracting, "Retracting" },{ RuntimeState::Pausing, "Pausing" },{ RuntimeState::Paused, "Paused" },{ RuntimeState::Stopping, "Stopping" },{ RuntimeState::Stopped, "Stopped" },{ RuntimeState::Aborting, "Aborting" } })// 结构体定义及序列化/反序列化
struct RobotMsg {int64_t timestamp;int level;int code;std::string source;std::vector<std::string> args;
};inline void to_json(json &j, const RobotMsg &p)
{j = json{{"timestamp", p.timestamp},{"level", p.level},{"code", p.code},{"source", p.source},{"args", p.args}};
}inline void from_json(const json &j, RobotMsg &p)
{try {j.at("timestamp").get_to(p.timestamp);j.at("level").get_to(p.level);j.at("code").get_to(p.code);j.at("source").get_to(p.source);j.at("args").get_to(p.args);} catch (const json::exception& e) {// 解析无效p.code = -1;// 或者抛出异常// throw std::runtime_error("Failed to parse JSON: " + std::string(e.what()));}
}

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

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

相关文章

Spring Boot框架的知识分类技术解析

2 开发技术 2.1 VUE框架 Vue.js&#xff08;读音 /vjuː/, 类似于 view&#xff09; 是一套构建用户界面的渐进式框架。 Vue 只关注视图层&#xff0c; 采用自底向上增量开发的设计。 Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 2.2 Mysql数据库 …

Knowledge Graph-Enhanced Large Language Models via Path Selection

研究背景 研究问题&#xff1a;这篇文章要解决的问题是大型语言模型&#xff08;LLMs&#xff09;在生成输出时存在的事实不准确性&#xff0c;即所谓的幻觉问题。尽管LLMs在各种实际应用中表现出色&#xff0c;但当遇到超出训练语料库范围的新知识时&#xff0c;它们通常会生…

Spark中的宽窄依赖

一、什么是依赖关系 这里通过一张图来解释&#xff1a; result_rdd是由tuple_rdd使用reduceByKey算子得到的&#xff0c; 而tuple_rdd是由word_rdd使用map算子得到的&#xff0c;word_rdd又是由input_rdd使用flatMap算子得到的。它们之间的关系就称为依赖关系&#xff01; 二…

实现uniapp-微信小程序 搜索框+上拉加载+下拉刷新

pages.json 中的配置 { "path": "pages/message", "style": { "navigationBarTitleText": "消息", "enablePullDownRefresh": true, "onReachBottomDistance": 50 } }, <template><view class…

在vscode中如何利用git 查看某一个文件的提交记录

在 Visual Studio Code (VSCode) 中&#xff0c;你可以使用内置的 Git 集成来查看某个文件的提交历史。以下是具体步骤&#xff1a; 使用 VSCode 内置 Git 功能 打开项目&#xff1a; 打开你的项目文件夹&#xff0c;确保该项目已经是一个 Git 仓库&#xff08;即项目根目录下…

如何用python求导数

打开python运行环境。 导入微分的模块包&#xff1a;from sympy import *。 定义符号变量&#xff1a;x symbols(x) 定义一个函数&#xff1a;f x**9 diff diff(f,x)求导 最后输入diff&#xff0c;即可显示其变量值了。

Protobuf——基本使用

什么是Protobuf Protobuf是 Google的⼀种语⾔⽆关、平台⽆关、可扩展的序列化结构数据的⽅法&#xff0c;它可⽤于&#xff08;数据&#xff09;通信协议、数据存储等。 Protobuf类比于XML&#xff0c;是一种灵活&#xff0c;高效&#xff0c;自动化机制的结构数据序列化方法&…

【人工智能】ChatGPT多模型感知态识别

目录 ChatGPT辅助细化知识增强&#xff01;一、研究背景二、模型结构和代码任务流程一&#xff1a;启发式生成 三、数据集介绍三、性能展示实现过程运行过程训练过程 ChatGPT辅助细化知识增强&#xff01; 多模态命名实体识别&#xff08;MNER&#xff09;最近引起了广泛关注。…

Spring源码(十二):Spring MVC之Spring Boot

本篇将详细讨论Spring Boot 的启动/加载、处理请求的具体流程。我们先从一个简单的Spring Boot项目日志开始分析&#xff08;这里假设读者已经仔细阅读完了前面的文章&#xff0c;且对Spring源码有一定深度的了解&#xff0c;否则会看得一脸懵逼&#xff09;。 本文为2024重置…

c语言-教零基础/新手入门

C 简介 一提到语言这个词语&#xff0c;自然会想到的是像英语&#xff0c;汉语等这样的自然语言&#xff0c;因为它是人和人交换信息不可缺少的工具。而今天计算机普遍了我们生活的每一个角落&#xff0c;除了人和人的相互交流之外&#xff0c;我们必须和计算机交流。就像人类…

【安装配置教程】二、VMware安装并配置ubuntu22.04

一、准备&#xff1a; 虚拟机安装ubuntu&#xff0c;首先要先找到一个镜像&#xff0c;可以去ubuntu官方下载一个&#xff0c;地址&#xff1a;下载Ubuntu桌面系统 | Ubuntu&#xff0c;下载好iso的镜像文件后保存好&#xff0c;接下来打开VMware。 二、安装&#xff…

立体视觉的核心技术:视差计算与图像校正详解

立体视觉的核心技术&#xff1a;视差计算与图像校正详解 在立体视觉中&#xff0c;通过双目相机&#xff08;即左右两台相机&#xff09;的不同视角捕获的图像&#xff0c;结合几何关系&#xff0c;我们可以推算出场景中物体的深度。本文将深入讲解如何基于视差&#xff08;di…

深度学习基础练习:从pytorch API出发复现LSTM与LSTMP

2024/11/5-2024/11/7&#xff1a; 前置知识&#xff1a; [译] 理解 LSTM(Long Short-Term Memory, LSTM) 网络 - wangduo - 博客园 【官方双语】LSTM&#xff08;长短期记忆神经网络&#xff09;StatQuest_哔哩哔哩_bilibili 大部分思路来自于&#xff1a; PyTorch LSTM和LSTMP…

scala学习记录,Set,Map

set&#xff1a;集合&#xff0c;表示没有重复元素的集合&#xff0c;特点&#xff1a;唯一 语法格式&#xff1a;val 变量名 Set [类型]&#xff08;元素1&#xff0c;元素2...&#xff09; 可变不可变 可变&#xff08;mutable&#xff09;可对元素进行添加&#xff0c;删…

Docker了解

Docker是一种容器化技术&#xff0c;它可以将应用程序和其依赖项打包到一个独立的、可移植的容器中&#xff0c;以便在不同的环境中运行。Docker基于Linux操作系统的容器化技术&#xff0c;可以提供更轻量、更快速、更灵活、更一致的应用部署和管理方式。 Docker的基本概念包括…

‘conda‘ 不是内部或外部命令,也不是可运行的程序或批处理文件,Miniconda

下载了conda&#xff0c;但是在cmd里执行conda --version会显示’conda’ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 原因是环境变量里没有添加conda&#xff0c;无法识别路径。 需要在系统环境变量里添加如下路径&#xff1a; 保存之后重新打开cmd&am…

《TCP/IP网络编程》学习笔记 | Chapter 4:基于TCP的服务器端/客户端(1)

《TCP/IP网络编程》学习笔记 | Chapter 4&#xff1a;基于TCP的服务器端/客户端&#xff08;1&#xff09; 《TCP/IP网络编程》学习笔记 | Chapter 4&#xff1a;基于TCP的服务器端/客户端&#xff08;1&#xff09;理解TCP和UDPTCP/IP协议栈TCP/IP协议的诞生背景链路层网络层T…

【C语言】。末尼

用js写一个冒泡排序 当然可以。在JavaScript中&#xff0c;你可以使用递归的方式来实现冒泡排序算法。这是一个简单的示例&#xff1a; function bubbleSort(arr) { let len arr.length; if(len < 1){ return arr; // 如果数组只有一个元素或为空&#xf…

深度学习笔记12

1.神经网络的代价函数 神经网络可同时用于解决分类问题和回归问题&#xff0c;对于不同的问题会在输出层后&#xff0c;加上不同的变换函数。一般来说&#xff0c;回归问题使用恒等函数,分类问题使用sigmoid或softmax函数。而不同的变换函数&#xff0c;也对应不同的代价函数。…

RabbitMQ队列详细属性(重要)

RabbitMQ队列详细属性 1、队列的属性介绍1.1、Type&#xff1a;队列类型1.2、Name&#xff1a;队列名称1.3、Durability&#xff1a;声明队列是否持久化1.4、Auto delete&#xff1a; 是否自动删除1.5、Exclusive&#xff1a;1.6、Arguments&#xff1a;队列的其他属性&#xf…