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.mzph.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;为后续的文本分…