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
是一个自定义的结构体,field1
和 field2
是它的字段。通过 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"
,反之亦然。
三、示例代码
假设我们有两个结构体 RobotMsg
和 RtdeRecipe
,以及两个枚举类型 RuntimeState
和 RobotModeType
。以下是完整的示例代码:
#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())); } }
到此这篇关于C++ 中的 JSON 序列化和反序列化:结构体与枚举类型的处理的文章就介绍到这了,更多相关C++ JSON 序列化和反序列化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!