005-nlohmann/json 基礎方法-C++開源庫108杰

《二、基礎方法》:節點訪問、值獲取、顯式 vs 隱式、異常處理、迭代器、類型檢測、異常處理……一節課搞定C++處理JSON數據85%的需求……

在這里插入圖片描述

JSON 字段的簡單類型包括:number、boolean、string 和 null(即空值);復雜類型則有 對象(Object)和數組(Array)兩類。

1 節點與值

訪問對象的指定名字的某個字段,可以使用 [“key”] ,訪問指定下標的某個元素,可以使用 [ index ] 來訪問(二者本質都是對 [] 操作符的重載),也可以通過方法 at(key/index) 來訪問。

當指定名字(key)或下標(index)并無對應數據可供訪問時,在 nlohmann/json 中,都被視為越界操作;此時,使用 [ ] 將“喜提”未定義(UB)的結果,而使用 at () 則得到異常。

通過 [] 或 at() 得到是 JSON 節點 (一個字段,或一個數組的一個元素);更多的時候,我們想要得到既定類型的值。

假設有這樣一個 nlohmann/json 對象:

nlohmann::json o = 
{{ "id","ORD20250409-191" },{ "customerID", 10345 },{ "items", {123, 94320, 8} },{ "totalAmount", 172.8 },{ "orderDate","2025/04/09" }
};

存在隱式和顯式兩種取值方法,如下:

int id1 = o["customerID"];  // 隱式
int id2;
id2 = o["customerID"]; // 隱式int id3 = o["customerID"].get<int>(); // 顯式,適用定義新變量int id4;
o["customerID"].get_to(id4); // 顯式,類型信息來自已定義的 id4

這里的顯式或隱式,指的類型轉換過程:JSON 節點類型到目標類型的轉換過程。隱式轉換會在以下兩點都滿足時,出現問題(造成編譯失敗):

  1. 目標類型重載了賦值操作符(即: = );
  2. 轉換時,目標對象是已定義變量(即:確實在為某個“老”對象賦值,而非在構造新對象)。

如需進一步了解隱式轉換出錯的原因,建議到 d2school.com 對應課堂閱讀擴展內容。

nlohmann/json官方推薦使用 get() 或 get_to (…) 顯式指定要轉換的目標類型。如果需要的是更嚴格項目管理,可以在項目中定義全局宏:JSON_USE_IMPLICIT_CONVERSIONS=0以禁用隱式取值,如是CMake項目,在CMakeList.txt 內添加代碼: SET (JSON_ImplicitConversions OFF),可得相同效果。

2 迭代器

借助迭代器,有四種 for 循環可用以迭代 JSON 對象的內容(假設 o 為 某json對象):

  • 循環1
for (auto it = o.begin(); it != o.end(); ++it)
{cout << it.key() << ":" << it.value() << "\n";
}
  • 循環2
for (auto it : o.items()) // 本質同循環1
{cout << it.key() << ":" << it.value() << "\n";
}
  • 循環3
for (auto v : o)  // 此時只有 value,因此比較適合遍歷數組節點
{cout << v << "\n";
}
  • 循環4
for (auto & [k, v] : o.items()) // 需 c++17 結構化綁定支持
{cout << k << ":" << v << "\n";
}

3 異常

nlohmann/json 日常操作中,有三種常見異常類型(它們的基類都是 nlohmann::json::exception)。

  • json::parse_error / 解析出錯

解析的數據中,存在格式(包括編碼)非法的數據,典型如:包含了非 UNICODE 編碼的漢字內容。nlohmann/json 支持的UNICODE編碼具體包括:UTF-8、UTF-16、UTF-32等。

注:“注釋”在 JSON 標準規范中,也是一種非常格式,但因為太常見,所以 nlohmann/json 提供了支持(非默認),詳見視頻一(快速認識)。

  • json::out_of_range / 越界訪問

使用 at(key/index) 訪問數據時,查找無指定字段名或下標對應的數據時,即拋出該異常。

  • json::type_error / 類型不匹配

典型如,對一個非對象、非數組類型的JSON節點,執行 push_back(新元素) 操作。

4 視頻2:基礎方法

010-nlohmann/json-2-基礎方法

5 示例項目-常用方法

  • 報文 demo.json
{"name" : "丁小明","age" : 12
}
  • 代碼
#include <cassert>#include <iostream>
#include <fstream>
#include <string>
#include <vector>#include <nlohmann/json.hpp>using json = nlohmann::json;int main()
{nlohmann::json o1 = {{ "id","ORD20250409-191" },{ "customerID", 10345 },{ "items", {123, 94320, 8} },{ "totalAmount", 172.8 },{ "orderDate","2025/04/09" }};std::cout << o1["id"] << std::endl;std::cout << o1["customerID"] << std::endl;std::cout << o1["items"] << std::endl;std::cout << o1["totalAmount"] << std::endl;std::cout << o1["orderDate"] << std::endl;auto node = o1["id"];std::cout << "node type-name is :\n" << typeid(node).name() << std::endl;// 隱式轉換類型,以獲取值{std::string id1 = o1["id"];int customerID = o1["customerID"];std::cout << id1 << "," << customerID << std::endl;}// 顯式轉換類型,以獲取值{auto id2 = o1["id"].get<std::string>();auto customerID2 = o1["customerID"].get<int>();std::cout << id2 << "," << customerID2 << std::endl;}{double totalAmount;o1["totalAmount"].get_to(totalAmount);std::cout << totalAmount << std::endl;std::cout << o1["totalAmount"].get_to(totalAmount) << std::endl;        }// find、at {json o; o["name"] = "丁小明";o["age"] = 12;try{std::cout << o["Name"].get<std::string>() << " is "<< o["age"].get<int>() <<std::endl;}catch(std::exception const& e){std::cout << e.what() << std::endl;}auto it = o.find("Name1");if (it != o.end()){std::cout << it->get<std::string>() << std::endl;}else{std::cerr << "no found field : Name1." << std::endl;}try{std::cout << o.at("NAME").get<std::string>() << " is "<< o["age"].get<int>() <<std::endl;}catch(std::exception const& e){std::cout << e.what() << std::endl;}        std::cout << o.dump(2) << std::endl;}// 迭代器、循環{for (auto const it : o1.items()){            std::cout << it.key() << " ==> " << it.value() << "\ttype : " << it.value().type_name() << std::endl;}std::cout << "==================\n";for (auto [k, v] : o1.items()){            std::cout << k << " ==> " << v << "\ttype : " << v.type_name() << std::endl;}o1["items"].push_back(999);std::cout << o1["items"] << std::endl;}// 異常: 非法JSON報文{std::string s = "\"Hello JSON!——第2學堂!\"";try{auto j = json::parse(s);std::cout << j.dump() << std::endl;}catch(json::parse_error const& e){std::cerr << e.id << "->" << e.what() << std::endl;}        }// 從文件讀{// 請填寫你的 demo.json 的實際位置std::ifstream ifs ("D:\\...\\CommonlyUsedJSON\\demo.json");if (!ifs){std::cerr << "open file fail!" << std::endl;return -1;}try{std::cout << "== read from file : \n";auto j = json::parse(ifs);std::cout << j.dump(2) << std::endl;}catch(json::parse_error const& e){std::cerr << e.what() << std::endl;}}// 異常:嘗試和類型不匹配的行為{using namespace nlohmann::literals;json j = R"({"id" : "Hello!","items": [1, 2, 3]})"_json;try{j.at("items").push_back(4);j.at("id").push_back('a');}catch(json::type_error const& e){std::cerr << e.what() << std::endl;}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/78743.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78743.shtml
英文地址,請注明出處:http://en.pswp.cn/web/78743.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HarmonyOS 5.0 分布式數據協同與跨設備同步??

大家好&#xff0c;我是 V 哥。 使用 Mate 70有一段時間了&#xff0c;系統的絲滑使用起來那是爽得不要不要的&#xff0c;隨著越來越多的應用適配&#xff0c;目前使用起來已經和4.3的兼容版本功能差異無礙了&#xff0c;還有些純血鴻蒙獨特的能力很是好用&#xff0c;比如&am…

Linux云計算訓練營筆記day02(Linux、計算機網絡、進制)

Linux 是一個操作系統 Linux版本 RedHat Rocky Linux CentOS7 Linux Ubuntu Linux Debian Linux Deepin Linux 登錄用戶 管理員 root a 普通用戶 nsd a 打開終端 放大: ctrl shift 縮小: ctrl - 命令行提示符 [rootlocalhost ~]# ~ 家目錄 /root 當前登錄的用戶…

macOS 安裝了Docker Desktop版終端docker 命令沒辦法使用

macOS 安裝了Docker Desktop版終端docker 命令沒辦法使用 1、檢查Docker Desktop能否正常運行。 確保Docker Desktop能正常運行。 2、檢查環境變量是否添加 1、添加環境變量 如果環境變量中沒有包含Docker的路徑&#xff0c;你可以手動添加。首先&#xff0c;找到Docker的…

Gradio全解20——Streaming:流式傳輸的多媒體應用(5)——基于WebRTC的攝像頭實時目標檢測

Gradio全解20——Streaming&#xff1a;流式傳輸的多媒體應用&#xff08;5&#xff09;——基于WebRTC的攝像頭實時目標檢測 本篇摘要20. Streaming&#xff1a;流式傳輸的多媒體應用20.5 基于WebRTC的攝像頭實時目標檢測20.5.1 環境配置及說明1. WebRTC2. TURN服務器 20.5.2 …

OSCP - Proving Grounds - NoName

主要知識點 linux命令注入SUID find提權 具體步驟 從nmap開始搜集信息&#xff0c;只開放了一個80端口 Nmap scan report for 192.168.171.15 Host is up (0.40s latency). Not shown: 65534 closed tcp ports (reset) PORT STATE SERVICE VERSION 80/tcp open http …

c++_csp-j算法 (6)_高精度算法(加減乘除)

高精度算法 C++高精度算法是指在C++編程語言中實現高精度計算的算法。在C++中,通常整數的范圍是有限的,超出這個范圍的整數計算會導致溢出。高精度算法的出現,使得C++程序能夠處理超出常規整數范圍的大整數計算,包括高精度加法、減法、乘法、除法等運算。 在C++中實現高精…

從OpenMP中的不兼容,窺探AI應用開發中的并行編程

在AI相關的項目開發中,偶然遇到下面這個問題: OMP: Error #15: Initializing libomp.dylib, but found libiomp5.dylib already initialized. OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the progr am. That is dangerous, sin…

vue2+element實現Table表格嵌套輸入框、選擇器、日期選擇器、表單彈出窗組件的行內編輯功能

vue2element實現Table表格嵌套輸入框、選擇器、日期選擇器、表單彈出窗組件的行內編輯功能 文章目錄 vue2element實現Table表格嵌套輸入框、選擇器、日期選擇器、表單彈出窗組件的行內編輯功能前言一、準備工作二、行內編輯1.嵌入Input文本輸入框1.1遇到問題1.文本框內容修改失…

c#OdbcDataReader的數據讀取

先有如下c#示例代碼&#xff1a; string strconnect "DSNcustom;UIDsa;PWD123456;" OdbcConnection odbc new OdbcConnection(strconnect); odbc.Open(); if (odbc.State ! System.Data.ConnectionState.Open) { return; } string strSql "select ID from my…

【HTML5】老式放映機原理-實現圖片無縫滾動

老式放映機原理-實現圖片無縫滾動 實現思路&#xff1a; 頁面設計部分——先將視口div設置為相對定位&#xff0c;再視口div里面嵌套一個類似“膠卷”的div,把該div設置為絕對定位&#xff0c;此時“膠卷"會掛靠在視口上面&#xff0c;再將“膠卷”的left屬性設置為負值…

LeetCode 1781. 所有子字符串美麗值之和 題解

示例 輸入&#xff1a;s "aabcb" 輸出&#xff1a;5 解釋&#xff1a;美麗值不為零的字符串包括 ["aab","aabc","aabcb","abcb","bcb"] &#xff0c;每一個字符串的美麗值都為 1這題光用文字解說還是無法達到講…

2025ACTF Web部分題解

文章目錄 ACTF uploadnot so web 1not so web 2 ACTF upload 前面登錄隨便輸入可以進入文件上傳頁面, 隨便上傳一張圖片, 發現路由存在file_path參數, 嘗試路徑穿越讀取文件 發現可以成功讀取 讀取源碼 /upload?file_path../app.pyimport uuid import os import hashlib im…

雙目標清單——AI與思維模型【96】

一、定義 雙目標清單思維模型是一種將決策或任務分解為兩個主要目標&#xff0c;并分別列出相關要素和行動步驟的思維方式。這兩個目標通常具有相互關聯又有所側重的特點&#xff0c;通過明確并列出與每個目標相關的具體事項&#xff0c;有助于更清晰地分析問題、制定計劃和分…

深度學習系統學習系列【6】之深度學習技巧

文章目錄 數據集準備數據集擴展數據預處理1. 0均值&#xff08;Zero Centralization&#xff09;代碼實現 2. 歸一化&#xff08;Normalization&#xff09;代碼實現 3. 主成分分析&#xff08;Principal Component Analysis, PCA&#xff09;實現步驟代碼實現 4. 白化&#xf…

rfsoc petalinux適配調試記錄

1。安裝虛擬機 2.設置共享文件夾 https://xinzhi.wenda.so.com/a/1668239544201149先設置文件夾路徑 vmware 12 下安裝 ubuntu 16.04 后&#xff0c;按往常的慣例安裝 vmware-tools&#xff0c;安裝時提示建議使用 open-vm-tools&#xff0c;于是放棄 vmware-tools 的安裝&am…

# YOLOv1:開啟實時目標檢測的新時代

YOLOv1&#xff1a;開啟實時目標檢測的新時代 在計算機視覺領域&#xff0c;目標檢測一直是研究的熱點和難點問題。它不僅需要準確地識別出圖像中的物體&#xff0c;還需要確定這些物體的位置。YOLO&#xff08;You Only Look Once&#xff09;系列算法以其高效的實時目標檢測…

uni-app vue3 實現72小時倒計時功能

功能介紹 &#xff0c;數組項有一個下單時間 &#xff0c;比如今天下單在72小時內可以繼續支付&#xff0c;超過則默認取消訂單 頁面按鈕處 加上倒計時 <!-- 倒計時 --> <text v-if"item.timeLeft > 0">{{ formatTime(item.remaining) }}</text&g…

一周學會Pandas2 Python數據處理與分析-Pandas2數據類型轉換操作

鋒哥原創的Pandas2 Python數據處理與分析 視頻教程&#xff1a; 2025版 Pandas2 Python數據處理與分析 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili Pandas 提供了靈活的方法來處理數據類型轉換&#xff0c;以下是常見操作及代碼示例&#xff1a; 1. 查看數據類型 …

LLM損失函數面試會問到的

介紹一下KL散度 KL&#xff08;Kullback-Leibler散度衡量了兩個概率分布之間的差異。其公式為&#xff1a; D K L ( P / / Q ) ? ∑ x ∈ X P ( x ) log ? 1 P ( x ) ∑ x ∈ X P ( x ) log ? 1 Q ( x ) D_{KL}(P//Q)-\sum_{x\in X}P(x)\log\frac{1}{P(x)}\sum_{x\in X}…

基于CBOW模型的詞向量訓練實戰:從原理到PyTorch實現

基于CBOW模型的詞向量訓練實戰&#xff1a;從原理到PyTorch實現 在自然語言處理&#xff08;NLP&#xff09;領域&#xff0c;詞向量是將單詞映射為計算機可處理的數值向量的重要方式。通過詞向量&#xff0c;單詞之間的語義關系能夠以數學形式表達&#xff0c;為后續的文本分…