了解 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;
}