当前位置: 首页 > news >正文

【C++】使用 nlohmann 解析 json 文件

引言

nlohman json GitHub - nlohmann/json: JSON for Modern C++ 是一个为现代C++(C++11)设计的JSON解析库,主要特点是

  • 易于集成,仅需一个头文件,无需安装依赖

  • 易于使用,可以和STL无缝对接,使用体验近似python中的json

常见用法

1. json初始化

1.1 从文件初始化

std::ifstream in_file("test.json");
nlohmann::json doc;
if (!in_file.is_open()) {exit(1);
}
in_file >> doc;
in_file.close();

1.2 从字符串初始化

方式1

nlohmann::json doc = R"({"key1":"value1", "key2":[1,2,3]})"_json;
// nlohmann::json doc = "{\"key1\":\"value1\", \"key2\":[1,2,3]}"_json; // 此种情况下需要对json字符串中的双引号进行转义
  • R表示json字符串中的特殊字符均按照字符本身进行解析,而不需要进行转义,如双引号、反斜杠等字符

  • _json结尾表示其是一个json对象

方式2

std::string info = R"({"key1":"value1", "key2":[1,2,3]})";
nlohmann::json doc = nlohmann::json::parse(info);
  • 调用json::parse方法,通过传入一个字符串进行构造,此时不以 _json结尾

1.3 直接构造json对象

方式1

// {"key1":"value1","key2":[1,2,3],"key3":{"key":"val"}}
nlohmann::json doc = {{"key1", "value1"}, {"key2", {1,2,3}}, {"key3", {{"key", "val"}}}};
  • 最外层的花括号表示一个json object

  • 里面的每一对花括号的第一个元素为key,第二个元素为value,用’,'分割

  • 注意:单对花括号包裹的是array,两对花括号包裹的才是json object,如:

    • {1, 2}是一个array,即[1, 2]

    • {{1, 2}}是一个object,即{1:2},key为1,value为2

方式2

// {"app":"wechat","array":[1,2,4],"obj":{"age":15,"name":"zs","sex":"m"}}
nlohmann::json doc;
doc["app"] = "wechat";  // 添加一个k-v,若key存在则覆盖value
doc["array"] = {1,2,3}; // 添加一个数组
doc["array"].emplace_back(4); // 数组添加一个元素
doc["array"].erase(2); // 删除下标为2的元素
doc["obj"] = {{"name", "zs"}, {"age", 15}}; // 添加一个object
doc["obj"].push_back({"sex", "m"}); // 通过push方法添加一个k-v,若key存在则忽略,不会覆盖value
doc.push_back({"app", "qq"}); // key存在,故忽略

2. json访问

json展开如下:

{"retCode": 0,"retMSg": "成功","data": [{"name": "李雷","id": "001","score": {"Chinese": 80,"Math": 95},"schoolInfo": [{"School_name": "清华"},{"School_name": "北大"}]},{"name": "韩梅梅","id": "002","score": {"Chinese": 90,"Math": 80},"schoolInfo": [{"School_name": "清华"},{"School_name": "北大"}]}]
}

循环遍历

std::string info = R"({"retCode":0,"retMSg":"成功","data":[{"name":"李雷","id":"001","score":{"Chinese":80,"Math":95},"schoolInfo":[{"School_name":"清华"},{"School_name":"北大"}]},{"name":"韩梅梅","id":"002","score":{"Chinese":90,"Math":80},"schoolInfo":[{"School_name":"清华"},{"School_name":"北大"}]}]})";
try {nlohmann::json doc = nlohmann::json::parse(info);
} catch (std::expection& e){// json转化失败会抛出异常,如json格式错误等std::cout << e.what() << std::endl;
}
// 循环遍历
for (auto& item : doc.items()) {const std::string& key = item.key();auto& value = item.value(); // 用引用减少拷贝if (value.is_number()) {auto val = value.get<int>(); // 推导为int,如果是浮点型,转化为int则只保留整数部分// int val = value;          // 强转为int型// auto val = value.get<uint32_t>();// auto val = value.get<double>();} else if (value.is_string()) {const std::string& str = value;// std::string str = value;} else if (value.is_array()) { // value是一个数组int len = value.size();for (int i = 0; i < len; ++i) {if (value[i].is_object()) {;} else if (value[i].is_string()) {;}}} else if (value.is_object()) { // value是一个jsonfor(auto& item_2 : value.items()) {;                       // 类似处理}} else if (value.is_boolean()) {bool b = value; // 或者直接用value进行传参,他会隐式转换为bool型}
}

指定key遍历

std::string info = R"({"retCode":0,"retMSg":"成功","data":[{"name":"李雷","id":"001","score":{"Chinese":80,"Math":95},"schoolInfo":[{"School_name":"清华"},{"School_name":"北大"}]},{"name":"韩梅梅","id":"002","score":{"Chinese":90,"Math":80},"schoolInfo":[{"School_name":"清华"},{"School_name":"北大"}]}]})";
nlohmann::json doc = nlohmann::json::parse(info);
if (doc.contains("retCode") && doc["retCode"].is_number()) {int retCode = doc["retCode"];
}
if (doc.contains("data") && doc["data"].is_array()) {nlohmann::json& doc_arr = doc["data"];int len = doc_arr.size();
} else if (doc.contains("data") && doc["data"].is_object()) {nlohmann::json& doc_json = doc["data"];
}

访问key的几种方式

// 1. 直接通过key访问
std::string retMsg = doc["retMSg"];  // key不存在会出core(所以要判断key是否存在),类型转换失败也会core
// 2. 通过at方法访问
std::string retMsg = doc.at("retMSg"); // 同上,不同点在于at方法可以抛出异常(如果key不存在)
  • 两种方式正常情况下返回的结果都是nlohmann::json对象,并且可以隐式转化为string以及各种基本类型

  • 为了避免上述可能出现的问题,直接访问key对应的value时,尽量按如下方式编写程序:

    1. 先判断key是否存在(contains)

    2. 再判断key的类型,key类型相关的判断方法如下:

    方法含义
    is_number是否为数字(int、uint32_t、uint64_t、double等)
    is_boolean是否为bool
    is_string是否为字符串
    is_array是否为数组
    is_object是否为json
  • 当然也可以通过捕获异常的方式来达到避免程序出错的目的,注意由于doc[“retMSg”]这种访问方式不能抛出异常,应该使用doc.at(“retMSg”)这种方式来访问。

3. json序列化

json序列化就是将json对象序列化成json格式的字符串或者存储到文本文件

序列化为json字符串

string str = doc.dump();

保存为json文件

nlohmann::json doc;doc["app"] = "wechat";
doc["age"] = 17;std::ofstream out_file("test.json");
out_file << doc;

相关文章:

【C++】使用 nlohmann 解析 json 文件

引言 nlohman json GitHub - nlohmann/json: JSON for Modern C 是一个为现代C&#xff08;C11&#xff09;设计的JSON解析库&#xff0c;主要特点是 易于集成&#xff0c;仅需一个头文件&#xff0c;无需安装依赖 易于使用&#xff0c;可以和STL无缝对接&#xff0c;使用体验…...

Nginx到底是什么,他能干什么?

目录 Ngnix是什么&#xff0c;它是用来做什么的呢&#xff1f; 一。Nginx简介 二&#xff0c;为什么要用Nginx呢&#xff1f; 二。Nginx应用 1.HTTP代理和反向代理 2.负载均衡 Ngnix是什么&#xff0c;它是用来做什么的呢&#xff1f; 一。Nginx简介 Nginx是enginex的简写&…...

如何判断一个java对象还活着

引用计数算法 引用计数器的算法是这样的&#xff1a;在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一&#xff1b;任何时刻计数器为零的对象就是不可能再被使用的。 缺点&#x…...

Go语言基础之结构体

Go语言中没有“类”的概念&#xff0c;也不支持“类”的继承等面向对象的概念。Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。 类型别名和自定义类型 自定义类型 在Go语言中有一些基本的数据类型&#xff0c;如string、整型、浮点型、布尔等数据…...

前端食堂技术周刊第 96 期:2023 CSS 状态、Nuxt 3.7、TypeScript 5.2、eBay 性能优化、贝塞尔曲线

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;冰镇黑乌龙 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 大家好&#xff0c;我是童欧巴。欢迎来到前端食堂技术周刊&#xff0c;我们先来看…...

一文总结Redis知识点

目录 为什么基于MySQL又出现Redis&#xff1f;Redis的优点&#xff1f;Redis支持的基本命令Redis支持的数据结构1 String2 List3 Set4 Sorted Set5 Hash6 Stream 消息队列7 Geospatial 地理空间8 Bitmap 位图9 Bitfield 位域10 HyperLogLog Redis是单线程还是多线程&#xff1f…...

ARM寄存器组

CM3 拥有通用寄存器 R0‐R15 以及一些特殊功能寄存器。 R0-R7&#xff0c;通用目的寄存器 R0-R7也被称为低组寄存器&#xff0c;所有指令可以访问它们&#xff0c;它们的字长为32位&#xff0c;复位后的初始值是不可预料的。 R8-R12&#xff0c;通用目的寄存器 R8-R12也被称…...

Windows查看当前文件夹下的所有.c文件的个数

在Windows的命令提示符&#xff08;CMD&#xff09;中&#xff0c;你可以使用for循环和dir命令结合起来&#xff0c;以计算当前文件夹下所有 .c 文件的个数。 下面是一个简单的示例&#xff0c;这个批处理脚本会计算当前目录下所有 .c 文件的个数&#xff1a; echo off setlo…...

ubuntu Qt 地图离线调用

ubuntu环境下在Qt上调用百度地图_ubuntu 百度地图_拿到金像奖上课那家店的博客-CSDN博客 【Qt初入江湖】Qt QtWebEngineWidgets 底层架构、原理详细描述_鱼弦的博客-CSDN博客 Ubuntu20.04 QT无法用Qwebengine控件的解决方案&#xff08;临时&#xff09;_cmsyq的博客-CSDN博客…...

Android Studio升级到Android API 33版本后,XML布局输入没有提示

低版本的Android Studio升级到Android API 33版本后&#xff0c;XML布局输入没有提示。查一下我目前使用的Android Studio 是2021年发布&#xff0c;而Android API 33是2022年发布的&#xff0c;这是由低版本升级到高版本造成不兼容的问题。解决方法有两种&#xff1a; 第一种…...

操作XML(带命名空间)

之前文章讲述了使用c# xpath如何操作xml文件&#xff0c;在实际开发项目中&#xff0c;遇到的很多xml文件都是带有命名空间的&#xff0c;如果还是用之前的代码获取&#xff0c;那将获取到null。 本文讲解操作代码有命名空间的Xml文件&#xff0c;以及多个命名空间的xml。 <…...

二叉搜索树(C++)

二叉搜索树 概念二叉搜索树的应用二叉搜索树的实现K模型基本结构和函数声明接口实现①find——查找关键码②Insert——插入关键码③Erase——删除关键码&#xff08;重点&#xff09;时间复杂度 源码&#xff08;整体&#xff09;非递归递归 KV模型 在使用C语言写数据结构阶段时…...

软件架构知识点

常用软件架构模型分类&#xff08;5种&#xff09; 软件架构建模方法&#xff08;模型4种&#xff09; 架构师分类&#xff08;微软4种&#xff09; 系统架构设计师的角色特质&#xff08;6种&#xff09; 计算机系统组成图谱 嵌入式操作系统的特点&#xff08;5个&#x…...

C语言日常刷题6

文章目录 题目答案与解析1234567 题目 1、以下对C语言函数的有关描述中&#xff0c;正确的有【多选】&#xff08; &#xff09; A: 在C语言中&#xff0c;一个函数一般由两个部分组成&#xff0c;它们是函数首部和函数体 B: 函数的实参和形参可以是相同的名字 C: 在main()中定…...

微信小程序使用stomp.js实现STOMP传输协议的实时聊天

简介&#xff1a; uniapp开发的小程序中使用 本来使用websocket&#xff0c;后端同事使用了stomp协议&#xff0c;导致前端也需要对应修改。 如何使用 在static/js中新建stomp.js和websocket.js&#xff0c;然后在需要使用的页面引入监听代码发送代码即可 代码如下&#x…...

基于饥饿游戏算法优化的BP神经网络(预测应用) - 附代码

基于饥饿游戏算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于饥饿游戏算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.饥饿游戏优化BP神经网络2.1 BP神经网络参数设置2.2 饥饿游戏算法应用 4.测试结果&#xff1a;5…...

[ 云计算 | AWS ] Java 应用中使用 Amazon S3 进行存储桶和对象操作完全指南

文章目录 一、前言二、所需 Maven 依赖三、先决必要的几个条件信息四、创建客户端连接五、Amazon S3 存储桶操作5.1. 创建桶5.2. 列出桶 六、Amazon S3 对象操作6.1. 上传对象6.2. 列出对象6.3. 下载对象6.4. 复制、重命名和移动对象6.5. 删除对象6.6. 删除多个对象 七、文末总…...

【Spring Boot】Spring Boot 配置 Hikari 数据库连接池

文章目录 前言配置 前言 数据库连接池是一个提高程序与数据库的连接的优化&#xff0c;连接池它主要作用是提高性能、节省资源、控制连接数、连接管理等操作&#xff1b; 程序中的线程池与之同理&#xff0c;都是为了优化、提高性能。 配置 spring:datasource:hikari:# 设置是…...

MR混合现实石油化工课堂情景实训教学演示

MR&#xff08;混合现实&#xff09;技术是一种结合了虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;优势的新型技术&#xff0c;在教育领域具有广阔的应用前景。在石油化工课堂中&#xff0c;MR混合现实情景实训教学的应用可以大大提高学生的学习效…...

php thinkphp 抖音支付,订单同步接口分享

1. 抖音支付 需要获取抖音小程序的AppID,AppSecret,需要配置回调地址&#xff0c;Token获取SALT 官方地址&#xff1a;支付&#xff0c;订单同步 以下干货仅针对于有一定开发基础的精英&#xff0c;0基础的止步。 public function DouyinPay($openId,$id,$body 抖音担保支付…...

家庭实验室方案:树莓派控制OpenClaw调用远程Qwen3-32B服务

家庭实验室方案&#xff1a;树莓派控制OpenClaw调用远程Qwen3-32B服务 1. 为什么选择树莓派OpenClaw组合 去年冬天&#xff0c;当我试图用语音控制家里的智能设备时&#xff0c;发现市面上的解决方案要么需要持续联网&#xff08;隐私堪忧&#xff09;&#xff0c;要么响应延…...

百度网盘真实下载地址高效提取与极速下载全攻略

百度网盘真实下载地址高效提取与极速下载全攻略 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 在日常工作与学习中&#xff0c;我们经常会遇到百度网盘分享链接下载速度受限、…...

告别公式复制烦恼!LaTeX2Word-Equation让跨平台公式处理效率提升10倍

告别公式复制烦恼&#xff01;LaTeX2Word-Equation让跨平台公式处理效率提升10倍 【免费下载链接】LaTeX2Word-Equation Copy LaTeX Equations as Word Equations, a Chrome Extension 项目地址: https://gitcode.com/gh_mirrors/la/LaTeX2Word-Equation 痛点诊断&#…...

为什么92%的FastAPI AI项目卡在流式响应?揭秘async generator阻塞根源与3种非阻塞调度模式

第一章&#xff1a;FastAPI 2.0 异步 AI 流式响应 如何实现快速接入FastAPI 2.0 原生强化了对异步流式响应&#xff08;StreamingResponse&#xff09;的支持&#xff0c;结合 async generator 可无缝对接大语言模型&#xff08;LLM&#xff09;的逐 token 输出场景&#xff0c…...

一键召唤AI画师!次元画室让角色设计变得如此简单

一键召唤AI画师&#xff01;次元画室让角色设计变得如此简单 你是否曾经有过这样的经历&#xff1f;脑海中浮现出一个绝妙的角色形象&#xff0c;却苦于无法将它完美呈现&#xff1b;或者为了设计游戏角色&#xff0c;不得不花费重金聘请专业画师&#xff1b;又或者作为小说作…...

2023年VSCode插件开发全指南:从零发布你的第一个扩展(TypeScript版)

2023年TypeScript生态下的VSCode插件开发实战 在当今开发者工具生态中&#xff0c;Visual Studio Code以其轻量化和高度可扩展性占据了绝对领先地位。根据2023年Stack Overflow开发者调查报告&#xff0c;VSCode以74.48%的使用率成为最受欢迎的代码编辑器。而插件系统正是其生态…...

OpenClaw智能剪贴板:GLM-4.7-Flash增强复制粘贴功能

OpenClaw智能剪贴板&#xff1a;GLM-4.7-Flash增强复制粘贴功能 1. 为什么我们需要更聪明的剪贴板 作为一个每天要和大量文本打交道的技术写作者&#xff0c;我经常陷入这样的困境&#xff1a;从网页复制的内容带着乱七八糟的格式&#xff0c;从PDF摘录的段落夹杂着换行符和乱…...

贪心-摆动序列、不重叠字串数量

Ref 贪心B站搜索-折半搜索 分发饼干 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(),g.end());sort(s.begin(),s.end());int cnt0;for(int i0,j0;i<g.size()&&j<s.size();){if(s[j]&…...

05-OpenClaw 自动生成 PPT 实战:每天节省 3 小时

作者&#xff1a;程序员小明儿 字数&#xff1a;约 9000 字 阅读时间&#xff1a;约 25 分钟 难度&#xff1a;⭐⭐⭐ 中级 系列&#xff1a;OpenClaw 实战 16 例&#xff08;第 5 篇&#xff09; 前置条件&#xff1a;已完成 OpenClaw 环境部署和基础配置写在前面 你是不是也这…...

深入解析串口通信:从RS232到RS485的工业应用实战

1. 串口通信的工业应用基础 第一次接触工业自动化项目时&#xff0c;我被现场密密麻麻的线缆搞得头晕眼花。直到老师傅指着角落里不起眼的两根双绞线说&#xff1a;"这条RS485总线控制着整条生产线的30台设备"&#xff0c;我才意识到串口通信在工业领域的强大之处。 …...