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()));
}
}
原文地址:https://blog.csdn.net/qq_35809147/article/details/143609344
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!