首页 > 编程语言 >在 C++ 中优雅地处理 JSON:nlohmann/json 库实践指南

在 C++ 中优雅地处理 JSON:nlohmann/json 库实践指南

时间:2025-01-07 17:33:11浏览次数:1  
标签:success JSON C++ nlohmann json 序列化

JSON (JavaScript Object Notation) 作为一种轻量级的数据交换格式,在现代软件开发中扮演着重要角色。在 C++ 开发中,nlohmann/json 库因其易用性和灵活性而广受欢迎。本文将通过实例介绍如何使用这个强大的库进行 JSON 数据的序列化和反序列化操作。

环境准备

首先,我们需要配置项目环境。这里使用 CMake 作为构建系统:

cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
project("nlohmann_json_test" CXX)

find_package(nlohmann_json CONFIG REQUIRED)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(nlohmann_json_test nlohmann_json_test.cpp)
target_link_libraries(nlohmann_json_test PRIVATE nlohmann_json::nlohmann_json)

数据结构定义

在示例中,我们定义了三个主要的数据结构:

struct Address {
    std::string street;
    std::string number;
    std::string postcode;

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(Address, street, number, postcode);
};

struct Person {
    std::string name;
    int age;
    std::vector<Address> addresses;

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(Person, name, age, addresses);
};

struct ApiResult {
    bool success;
    std::string message;
    json data;

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(ApiResult, success, message, data);
};

这里的关键是使用 NLOHMANN_DEFINE_TYPE_INTRUSIVE 宏,它自动为我们的结构体生成序列化和反序列化的代码。这大大简化了 JSON 转换过程,无需手动编写转换逻辑。

JSON 序列化示例

让我们看看如何将 C++ 对象序列化为 JSON:

Person person = {
    "John Doe",
    20,
    {
        {"Main St", "123", "12345"},
        {"Second St", "456", "67890"}
    }
};

// 序列化为 JSON
json j = person;
std::cout << j.dump(4) << std::endl;

序列化结果:

{
    "addresses": [
        {
            "number": "123",
            "postcode": "12345",
            "street": "Main St"
        },
        {
            "number": "456",
            "postcode": "67890",
            "street": "Second St"
        }
    ],
    "age": 20,
    "name": "John Doe"
}

JSON 反序列化示例

同样简单,我们可以将 JSON 字符串反序列化为 C++ 对象:

json j2 = R"(
    {
        "name": "Jane Doe",
        "age": 25,
        "addresses":[
            {
                "street":"jiangxia",
                "number":"258",
                "postcode":"54321"
            },
            {
                "street":"wuchang",
                "number":"369",
                "postcode":"12345"
            }
        ]
    }
)"_json;

Person person2;
j2.get_to(person2);

API 响应封装示例

在实际开发中,我们经常需要处理 API 响应。这里展示了如何使用 ApiResult 结构体封装不同类型的响应:

// 成功响应,携带数据
ApiResult ar1;
ar1.success = true;
ar1.message = "success";
ar1.data = person;
json jar1 = ar1;

// 错误响应
ApiResult ar2;
ar2.success = false;
ar2.message = "A fatal error has occurred";
ar2.data = nullptr;
json jar2 = ar2;

这将产生如下 JSON 输出:

成功响应:

{
    "data": {
        "addresses": [...],
        "age": 20,
        "name": "John Doe"
    },
    "message": "success",
    "success": true
}

错误响应:

{
    "data": null,
    "message": "A fatal error has occurred",
    "success": false
}

主要特点和优势

  1. 简单直观的 API:通过 NLOHMANN_DEFINE_TYPE_INTRUSIVE 宏,可以轻松实现序列化和反序列化。
  2. 类型安全:编译时类型检查,避免运行时错误。
  3. 灵活的数据处理:支持复杂的嵌套结构和各种数据类型。
  4. 现代 C++ 特性支持:与 C++11 及以上版本完全兼容。
  5. 错误处理:提供清晰的错误信息和异常处理机制。

注意事项

  1. 使用 NLOHMANN_DEFINE_TYPE_INTRUSIVE 时,需要确保所有成员变量都是可序列化的。
  2. 在处理大型 JSON 数据时,要注意内存使用。
  3. 对于非字符串类型的键,需要特别处理。
  4. C++20 提供了更简洁的结构体初始化语法,但要注意编译器支持情况。

标签:success,JSON,C++,nlohmann,json,序列化
From: https://www.cnblogs.com/linxmouse/p/18658022

相关文章

  • jacksonjson 反序列化localdatetime指定格式输出
    在使用Jackson进行JSON反序列化时,如果需要将JSON中的日期时间字符串转换为LocalDateTime类型,并指定特定的格式,可以使用@JsonFormat注解。以下是具体的使用方法:1.添加依赖确保你的项目中已经引入了Jackson依赖。如果使用Maven,可以在pom.xml中添加以下依赖:<depe......
  • DirectX 修复工具 V4.3 绿色增强版:完美解决 DirectX 和 C++ 问题,修复 0xc000007b 错误
    介绍DirectX修复工具V4.3是一款高效的系统修复工具,专为解决系统异常和C++运行库问题而设计,尤其对解决0xc000007b错误有着极高的修复率。本工具支持对所有版本的DirectX进行修复,并在增强版中新增了对C++运行库问题的修复,提供了一个全面且可靠的解决方案。主要功能......
  • JSON.stringify()时间date 结果减少了一天
    原因:关于日期对象的时区:JavaScript日期对象在内部以协调世界时(UTC)时间存储,但通常会根据浏览器的时区设置来进行显示,当您的日期对象序列化为JSON时,它将被转换为字符串,通常使用ISO8601格式,这个过程会导致日期时区信息的丢失JSON.stringify 在序列化日期对象时,会根据JavaScript日......
  • libfacedetection人脸检测C++代码实现Demo
    目录1简介2如何编译3注意事项4接口说明5演示Demo5.1开发环境5.2功能介绍5.3下载地址1简介        libfacedetection是一个基于CNN的人脸检测的开源库。CNN模型已在C源文件中转换为stasticvariales。源代码不依赖于任何其他库。你需要的只是一个......
  • 《 C++ 点滴漫谈: 十八 》写出无懈可击的代码:全面解析 C++ 的 explicit 和 implicit 显
    摘要在C++中,隐式和显式转换是程序设计中至关重要的概念,而关键字explicit则是掌控这一机制的核心工具。本文从基础概念出发,全面解析explicit和隐式转换的关系,深入探讨它们在构造函数、防止隐式类型转换错误等场景中的应用。通过对比分析隐式与显式的优缺点,以及C++11......
  • C++ Qt练习项目 QSpinBox和QDoubleSpinBos 未完待续
    个人学习笔记新建项目设计UI......
  • Jetbrains fleet 配置 C++开发环境(基于CMAKE和MinGW)
    Jetbrainsfleet配置C++开发环境1.安装JetbrainsFleet到Fleet下载页面下载Toolbox并安装Jetbrains-Fleet下载页安装完成后在任务栏打开Toolbox,在列表中选择安装fleet。2.为Fleet准备Workspace在适当的地方建立文件夹作为fleet的工作空间,并在fleet中打开。3......
  • 超级好用的C++实用库之服务包装类
    在C++开发中,服务包装类库是非常重要且实用的工具。它们可以显著简化代码编写,提高开发效率和代码可维护性。以下是几个超级好用的C++服务包装类库,以及如何使用它们来优化开发工作。常用的C++服务包装类库1.Boost.AsioBoost.Asio是一个跨平台的C++网络编程库,用于实现异步I/O操作......
  • leetcode 热题100(32. 最长有效括号)栈 c++
    链接:32.最长有效括号-力扣(LeetCode)给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。示例1:输入:s="(()"输出:2解释:最长有效括号子串是"()"示例2:输入:s=")()())"输出:4解释:最长有效括号子串是"()()"示例3:输入:s=""......
  • C++学习笔记#01——指针与链表
    在自学C++的时候,发现指针是一个很难绕开的东西,看了一些参考资料和别人的程序,写一些垃圾。Part1指针指针是一个指向一片内存地址的变量,相当于家的门牌号。我们即可以通过变量名来访问一个变量,也可以通过它对应的地址来访问。就像你的老师可以点你的名字找你,也可以找你宿舍的门......