自学内容网 自学内容网

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()));
    }
}

原文地址:https://blog.csdn.net/qq_35809147/article/details/143609344

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!