了解 nlohmann/json 的特点;理解编程中 “数据战场”划分的概念;迅速上手多种方式构建一个JSON对象;
1 特点与安装
nlohmann/json 是一个在 github 长期霸占 “JSON” 热搜版第1的C++JSON处理库。它的最大优点是与 C++ 标准库的容器数据(比如 std::map、std::vector)使用体验一致,并且搭配良好,比如,假设 strct T 能与JSON双向互换,则 std::vector 自然能与JSON双向互换。
在 msys2 ucrt64 环境下,安装命令为:
pacman -S mingw-w64-ucrt-x86_64-nlohmann-json
如果为了更好地兼容旧 Windows 系统,你选择的是 mingw64 环境,则该库名称为:mingw-w64-x86_64-nlohmann-json。
2 数据战场
一个 C++ 程序为什么需要使用到 JSON 数据?那是因为,程序即战场,数据即士兵,不同的战场需要不同的士兵。下图描述了“数据战场”的概念。
我们在 C++ 程序中自定义的数据,比如一个结构体,通常就是该程序中与业务最紧密结合,需要参与最多计算的数据,因此通常称为 “主战兵”;而JSON 数据常用作程序与外部环境的通信格式,因此被称为“通信兵”。nlohmann/json 是我们请来的 “雇佣兵”(三方库),它擅长以 C++ 结构模拟 JSON 语法,从而有效帮助我们的“主战兵”拥有变形金刚的能力……
在 “见证” 主战兵和通信兵如何快速互变之前,一定要先清楚二者之间存在一些重要差异:
- C++内置类型体系和JSON的类型体系并非一一对应
- JSON 不保证字段次序(如需要,可使用 nlohmann::ordered_json 类)
3 视频1:快速认识
009-nlohmann/json-1-快速认识
4 Hello JSON
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
/*
{
"id": "ORD20250409-191", //订单号
"customerID": 10345, //用户ID
"items": [123,94320,8], //商品货号列表
"totalAmount": 172.8, //总价
"orderDate": "2025/04/09" //下单日期
}
*/
int main()
{
json o1 =
{
{"id", "ORD20250409-191"},
{"customerID", 10345},
{"items", {123, 94320, 8}},
{"totalAmount", 172.8},
{"orderDate", "2025/04/09"}
};
std::cout << o1.dump(2) << std::endl;
json oArray = {123, 94320, 8};
std::cout << oArray.dump() << std::endl;
json oInt = 123;
json oString = "Tom";
json oBoolean = true;
std::cout << "int -> \t" << oInt.dump() << "\n";
std::cout << "string -> \t" << oString.dump() << "\n";
std::cout << "boolean -> \t" << oBoolean.dump() << "\n";
using namespace nlohmann::literals;
// 字符串常量 -> json 变量
json o2 = R"(
{
"id": "ORD20250409-191",
"customerID": 10345,
"items": [123,94320,8],
"totalAmount": 172.8,
"orderDate": "2025/04/09"
})"_json;
assert(o1 == o2);
std::cout << "\no2->\n" << o2.dump(2) << std::endl;
// 支持注释
std::string source = R"(
{
"id": "ORD20250409-191", // 订单ID
"customerID": 10345, // 用户ID
"items": [123,94320,8], // 包含商品的货号
"totalAmount": 172.8,
"orderDate": "2025/04/09"
})";
json o3 = json::parse(source, nullptr, true, true);
assert(o3 == o2);
std::cout << "\no3->\n" << o3.dump(2) << std::endl;
}