nlohmann json库使用

1,什么是 nlohman::json

1.1,下载地址

git repo: GitHub - nlohmann/json: JSON for Modern C++

1.2,基本介绍

nlohmann是一个C++的JSON库,它提供了方便的方式来解析、生成和操作JSON数据。该库由nlohmann编写,是一个开源项目,被广泛应用于C++开发中。

nlohmann库提供了简单易用的API,可以轻松地将JSON数据解析为C++对象,或者将C++对象序列化为JSON数据。它支持各种数据类型,包括字符串、数字、布尔值、数组和对象等。我们可以使用简洁的语法来访问和操作JSON数据,使得编写JSON处理代码变得更加简单和高效。

除了基本的JSON解析和生成功能,nlohmann库还提供了一些高级功能,如JSON合并、JSON差异比较、JSON数据查询等。这些功能可以帮助我们更方便地处理复杂的JSON数据,提高代码的可维护性和可读性。

2,具体解析示例

2.1,组成 json 串示例1

#include <iostream>  // 包含标准输入输出流的头文件
#include <nlohmann/json.hpp>  // 包含nlohmann/json库的头文件

using ordered_json = nlohmann::ordered_json;  // 定义别名ordered_json,映射到nlohmann库中的ordered_json类

int main() 
{
    ordered_json j;  // 创建ordered_json类型的变量j
    j["one"] = 1;  // 向j中添加键值对"one":1
    j["two"] = 2;  // 向j中添加键值对"two":2
    j["three"] = 3;  // 向j中添加键值对"three":3

    std::cout << j.dump(2) << '\n';  // 将JSON对象转换为字符串并打印输出,缩进为2个空格
}

这是主函数的定义,程序的入口点。

首先创建了一个ordered_json类型的变量j,然后向其添加了三个键值对,分别对应"one"、"two"和"three"这三个键,并将它们的值设置为1、2和3。

最后,通过调用j.dump(2)方法将JSON对象转换为字符串,并以格式化的方式打印输出到控制台。这里的参数2指定了缩进的空格数为2个空格。

运行结果:

{
  "one": 1,
  "two": 2,
  "three": 3
}

2.2,组成  json 串示例2

#include <iostream>  // 包含标准输入输出流的头文件
#include <nlohmann/json.hpp>  // 包含nlohmann/json库的头文件

// 定义一个输出函数,用于打印字典内容
template<typename Map>
void output(const char* prefix, const Map& m)
{
    std::cout << prefix << " = { ";
    for (auto& element : m)
    {
        std::cout << element.first << ":" << element.second << ' ';
    }
    std::cout << "}" << std::endl;
}

int main()
{
    // 创建并填充两个字典
    nlohmann::ordered_map<std::string, std::string> m_ordered; // 有序字典,按键顺序排序
    m_ordered["one"] = "eins";
    m_ordered["two"] = "zwei";
    m_ordered["three"] = "drei";

    std::map<std::string, std::string> m_std;// 普通字典,按键顺序排序,但不如有序字典稳定
    m_std["one"] = "eins";
    m_std["two"] = "zwei";
    m_std["three"] = "drei";

    // 输出:m_ordered按插入顺序排序,m_std按键排序
    output("m_ordered", m_ordered);
    output("m_std", m_std);

    // 删除并重新添加"one"键
    m_ordered.erase("one");  // 从有序字典中移除键值对
    m_ordered["one"] = "eins";  // 重新添加键值对到有序字典的末尾(因为之前已经删除)

    m_std.erase("one");  // 从普通字典中移除键值对
    m_std["one"] = "eins";  // 重新添加键值对到普通字典的末尾(因为之前已经删除)

    // 输出:m_ordered显示新添加的键在末尾;m_std仍然是按键排序的
    output("m_ordered", m_ordered);
    output("m_std", m_std);
}

运行结果:

m_ordered = { one:eins two:zwei three:drei }
m_std = { one:eins three:drei two:zwei }
m_ordered = { two:zwei three:drei one:eins }
m_std = { one:eins three:drei two:zwei }

2.3,解析 json 串示例1

#include <iostream>  // 包含标准输入输出流的头文件
#include <nlohmann/json.hpp>  // 包含nlohmann/json库的头文件

using json = nlohmann::json;  // 使用nlohmann::json类的别名json
using namespace nlohmann::literals;  // 使用nlohmann字面量命名空间

int main() 
{
    // 创建一个包含不同类型条目的JSON对象
    json j =
    {
        {"integer", 1},  // integer类型的键值对,值为1
        {"floating", 42.23},  // floating类型的键值对,值为42.23
        {"string", "hello world"},  // string类型的键值对,值为"hello world"
        {"boolean", true},  // boolean类型的键值对,值为true
        {"object", {{"key1", 1}, {"key2", 2}}},  // object类型的键值对,内部为一个包含两个元素的数组,元素分别为1和2
        {"array", {1, 2, 3}}  // array类型的键值对,内部为一个包含三个元素的数组,元素分别为1、2、3
    };

    // 访问存在的值
    int v_integer = j.value("/integer"_json_pointer, 0);  // 获取整数类型的值,如果不存在则默认为0
    double v_floating = j.value("/floating"_json_pointer, 47.11);  // 获取浮点数类型的值,如果不存在则默认为47.11

    // 访问不存在的值并依赖默认值
    std::string v_string = j.value("/nonexisting"_json_pointer, "oops");  // 获取字符串类型的值,如果不存在则默认为"oops"
    bool v_boolean = j.value("/nonexisting"_json_pointer, false);  // 获取布尔类型的值,如果不存在则默认为false

    // 输出值
    std::cout << std::boolalpha << v_integer << " " << v_floating
              << " " << v_string << " " << v_boolean << "\n";  // 打印出获取到的值,其中v_integer和v_boolean会以文本形式(true/false)输出,而v_floating会以科学计数法输出,v_string会原样输出
}

运行结果:

1 42.23 oops false

2.4,解析 json 串示例2

#include <iostream>  // 引入标准输入输出流头文件
#include <unordered_map>  // 引入无序映射容器头文件
#include <nlohmann/json.hpp>  // 引入nlohmann JSON库头文件

using json = nlohmann::json;  // 使用nlohmann::json类的别名json
using namespace nlohmann::literals;  // 使用nlohmann字面量命名空间

int main() 
{
    // 创建一个包含不同类型条目的JSON值
    json json_types =
    {
        {"boolean", true},  // boolean类型的键值对,值为true
        {
            "number", {  // number类型的键值对,内部为一个对象,包含两个属性:integer和floating-point
                {"integer", 42},  // integer类型的键值对,值为42
                {"floating-point", 17.23}  // floating-point类型的键值对,值为17.23
            }
        },
        {"string", "Hello, world!"},  // string类型的键值对,值为"Hello, world!"
        {"array", {1, 2, 3, 4, 5}},  // array类型的键值对,内部为一个数组,包含五个元素:1、2、3、4、5
        {"null", nullptr}  // null类型的键值对,值为nullptr(空指针)
    };

    bool v1;
    int v2;
    short v3;
    float v4;
    int v5;
    std::string v6;
    std::vector<short> v7;
    std::unordered_map<std::string, json> v8;

    // 使用显式转换将JSON值转换为相应的变量类型
    json_types["boolean"].get_to(v1);  // 将布尔值转换为布尔变量v1
    json_types["number"]["integer"].get_to(v2);  // 将整数值转换为整数变量v2和v3(这里存在重复赋值的问题)
    json_types["number"]["integer"].get_to(v3);  // 将整数值转换为整数变量v3(这里存在重复赋值的问题)
    json_types["number"]["floating-point"].get_to(v4);  // 将浮点数值转换为浮点数变量v4和v5(这里存在重复赋值的问题)
    json_types["number"]["floating-point"].get_to(v5);  // 将浮点数值转换为浮点数变量v5(这里存在重复赋值的问题)
    json_types["string"].get_to(v6);  // 将字符串值转换为字符串变量v6
    json_types["array"].get_to(v7);  // 将数组值转换为向量变量v7(这里存在重复赋值的问题)
    json_types.get_to(v8);  // 将整个JSON对象转换为无序映射变量v8(这里也存在重复赋值的问题)

    // 打印转换结果
    std::cout << v1 << '\n'; // 打印布尔变量v1的值(true)
    std::cout << v2 << ' ' << v3 << '\n'; // 打印重复赋值的整数变量v2和v3的值(42)和(42)
    std::cout << v4 << ' ' << v5 << '\n'; // 打印重复赋值的浮点数变量v4和v5的值(17.23)和(17.23)
    std::cout << v6 << '\n'; // 打印字符串变量v6的值(Hello, world!)

    for (auto i : v7) { // 遍历向量变量v7并打印每个元素(这里存在重复赋值的问题)
        std::cout << i << ' ';
    }
    std::cout << "\n\n";

    for (auto i : v8) { // 遍历无序映射变量v8并打印键值对(这里存在重复赋值的问题)
        std::cout << i.first << ": " << i.second << '\n';
    }
}

运行结果:

1
42 42
17.23 17
Hello, world!
1 2 3 4 5 

string: "Hello, world!"
number: {"floating-point":17.23,"integer":42}
null: null
boolean: true
array: [1,2,3,4,5]

2.5,解析 json 串示例3

complex.json

{
  "employees": [
    {
      "firstName": "John",
      "lastName": "Doe",
      "age": 30,
      "position": "Manager"
    },
    {
      "firstName": "Jane",
      "lastName": "Smith",
      "age": 25,
      "position": "Developer"
    }
  ],
  "projects": {
    "Project X": {
      "start_date": "2023-01-01",
      "end_date": "2023-12-31",
      "team_members": ["John Doe", "Jane Smith"]
    },
    "Project Y": {
      "start_date": "2024-01-01",
      "end_date": "2024-12-31",
      "team_members": ["Jane Smith"]
    }
  }
}
#include <iostream>  // 引入标准输入输出流头文件
#include <fstream>
#include <nlohmann/json.hpp>  // 引入nlohmann JSON库头文件

using json = nlohmann::json;  // 使用nlohmann::json类的别名json

int main() 
{
    std::ifstream file("complex.json");
    json data;
    file >> data;

    std::cout << "Employees:" << std::endl;
    for (const auto& employee : data["employees"]) {
        std::cout << employee["firstName"] << " " << employee["lastName"] << ", age: " << employee["age"] << ", position: " << employee["position"] << std::endl;
    }

    std::cout << "Projects:" << std::endl;
    for (const auto& project : data["projects"]) {
        std::cout << project.first << ":" << std::endl;
        std::cout << "  Start date: " << project.second["start_date"] << std::endl;
        std::cout << "  End date: " << project.second["end_date"] << std::endl;
        std::cout << "  Team members: ";
        for (const auto& member : project.second["team_members"]) {
            std::cout << member << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

运行结果:

Employees:
John Doe, age: 30, position: Manager
Jane Smith, age: 25, position: Developer

Projects:
Project X:
  Start date: 2023-01-01
  End date: 2023-12-31
  Team members: John Doe Jane Smith
Project Y:
  Start date: 2024-01-01
  End date: 2024-12-31
  Team members: Jane Smith

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值