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

 更新时间:2024年11月08日 12:11:08   作者:极地星光  
在 C++ 编程中,处理 JSON 数据是一项常见任务,特别是在需要与其他系统或前端进行数据交换时,本文将详细介绍如何使用 nlohmann::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()));
    }
}

到此这篇关于C++ 中的 JSON 序列化和反序列化:结构体与枚举类型的处理的文章就介绍到这了,更多相关C++ JSON 序列化和反序列化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Qt 数据库QSqlDatabase使用示例

    Qt 数据库QSqlDatabase使用示例

    本文主要介绍了Qt数据库QSqlDatabase使用示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-12-12
  • C++ Qt实现浏览器网页内嵌的音视频播放器

    C++ Qt实现浏览器网页内嵌的音视频播放器

    这篇文章主要为大家详细介绍了如何利用C++ Qt实现浏览器网页内嵌的音视频播放器,并支持软硬解码,支持音频,支持录像截图,支持多路播放等,感兴趣的可以了解下
    2024-01-01
  • C++实现旋转数组的二分查找

    C++实现旋转数组的二分查找

    这篇文章主要介绍了C++实现旋转数组的二分查找方法,涉及数组的操作,有值得借鉴的技巧,需要的朋友可以参考下
    2014-09-09
  • 探讨:C++中函数返回引用的注意事项

    探讨:C++中函数返回引用的注意事项

    本篇文章是对C++中函数返回引用的注意事项进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++实现一个简易版的事件(Event)的示例代码

    C++实现一个简易版的事件(Event)的示例代码

    之前在 windows系统中开发应用时, 遇到需要进行线程同步的时候几乎都是使用的事件内核对象 Event。本文为大家整理了C++实现一个简易版的事件(Event)的相关资料,需要的可以参考一下
    2022-11-11
  • C++类和对象补充

    C++类和对象补充

    类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量;创建对象的过程也叫类的实例化。每个对象都是类的一个具体实例(Instance),拥有类的成员变量和成员函数
    2021-10-10
  • 基于Windows API分解路径问题的详解

    基于Windows API分解路径问题的详解

    本篇文章是对Windows API分解路径进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 一文带你快速了解C/C++标准库中的ptrdiff_t

    一文带你快速了解C/C++标准库中的ptrdiff_t

    ptrdiff_t是C/C++标准库中定义的一个与机器相关的数据类型,ptrdiff_t类型变量通常用来保存两个指针减法操作的结果,下面这篇文章主要给大家介绍了关于C/C++标准库中ptrdiff_t的相关资料,需要的朋友可以参考下
    2022-11-11
  • C语言如何利用异或进行两个值的交换详解

    C语言如何利用异或进行两个值的交换详解

    最近在工作中遇到了两个值交换的需求,发现自己对异或有些忘记,所以索性写出来,方便以后需要的时候参考学习,下面这篇文章主要给大家介绍了关于C语言如何利用异或进行两个值的交换的相关资料,需要的朋友可以参考下。
    2017-09-09
  • C/C++中二进制文件&顺序读写详解及其作用介绍

    C/C++中二进制文件&顺序读写详解及其作用介绍

    这篇文章主要介绍了C/C++中二进制文件&顺序读写详解及其作用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09

最新评论