JsonCpp

参考文档:https://zhuanlan.zhihu.com/p/374319504

json是一种轻量级数据交换格式,易于阅读和编写,也易于机器解析和生成。使用json格式可以方便地在各个系统之间传递数据。在c++中,有许多开源的json库可以进行json的处理。比如:RapidJSON 、Boost.PropertyTree实现、 JsonCpp实现、Nlohmann.Json实现。本文将介绍JsonCpp开源库的json处理方法及实现。

JSON(JavaScript Object Notation) 是Douglas crockford于21世纪初指定的一种轻量级的数据交换格式,既易于人们阅读和编写,也易于机器的解析和生成。尽管JSON是JavaScript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯,因此其成为了理想的数据交换语言。

本篇主要讲解了使用C++语言对JSON文件进行的操作,包括环境配置、文件读取、文件写入。

一、环境配置

(一)jsoncpp库的下载

本文选择一个第三方库 jsoncpp 来解析 JSON。jsoncpp 是比较出名的 C++ JSON 解析库。在 JSON 官网也是首推的。

下载地址为:http://sourceforge.net/projects/jsoncpp。本文使用的 jsoncpp 版本为:0.5.0。

(二)基于Visual Studio2015的环境配置

这个老版本的配置方式较为简单,只需要添加相应的头文件即可。

(1)将文件中的include和src文件夹拷贝到vs工程的目录下。

(2)在工程属性栏附加包含目录中添加include的路径。

(3)在工程“源文件”添加上述src下lib_json下的cpp文件。

                                ​​​​​​​        ​​​​​​​ 

二、写入文件

这里我们先给出整体代码,输出结果如本篇开始所示,我们主要介绍基于类似于c++“map”的方式(以后简称map)和父子节点的形式。

#include <iostream>
#include <fstream>
#include <json/json.h>using namespace std;int main() {//根节点Json::Value root;//若直接使用“=”进行赋值,则默认该变量:为一个数或字符串root["Group Name"] = "Togehter"; //1.根节点"Group Name"和值"Togehter"root["Number"] = 2; //2.根节点"Number"和值2//若使用“append”则默认该变量:为向量的形式//3.根节点"Students"和值{"Zhangsan":[180,70], "Lisi":[165,50]}//3.1 Map形式root["Students"]["Zhangsan"].append(180);root["Students"]["Zhangsan"].append(70);root["Students"]["Lisi"].append(165);root["Students"]["Lisi"].append(50);//3.2父子节点形式Json::Value student;student["Zhangsan"].append(180);student["Zhangsan"].append(70);student["Lisi"].append(165);student["Lisi"].append(50);	root["Students"] = student;//格式化输出到文件  ofstream os;             //实例化输出类os.open("test.json", std::ios::out); //打开并指定文件以输出方式打开(往文件里写)if (!os.is_open())               //检查文件打开情况cout << "open file failed" << endl;Json::StyledWriter sw;      //定义格式化输出os << sw.write(root);       //输出到文件  os.close();                 //关闭文件return 0;
}

1. 首先定义根节点,针对一级子对象可以直接使用map的形式进行操作,这里若直接使用“=”进行赋值,则默认该变量为一个数或字符串;若使用“append”则默认该变量为向量的形式。

Json::Value root;
root["Group Name"] = "Togehter";
root["Number"] = 2;

2. 针对含有二级对象的内容,可以使用以下两种方式:

(1)map形式,这种方式较为简单,但缺点就是只能处理相对比较简单的二级对象。

在一级对象后直接跟不同的二级对象作为区分,并针对二级对象进行赋值或添加的操作。

root["Students"]["Zhangsan"].append(180);     //添加身高信息
root["Students"]["Zhangsan"].append(70);      //添加体重信息root["Students"]["Lisi"].append(165);         //添加身高信息
root["Students"]["Lisi"].append(50);          //添加体重信息

(2)父子节点的形式,缺点就是定义起来较为麻烦。

定义子节点,然后按照与根节点相同的方式对子节点进行处理,最后将其链接到根节点即可。

Json::Value student;                //定义子节点
student["Zhangsan"].append(180);
student["Zhangsan"].append(70);student["Lisi"].append(165);
student["Lisi"].append(50);root["Students"] = student;         //将子节点链接到根节点上

写入的Json文件格式如下:

三、读取文件

读取文件较为简单,这里就不展开详细讲解啦,大家可以参考下面的注释,上整体代码。

#include <iostream>
#include <fstream>
#include <json/json.h>using namespace std;int main() {Json::Reader reader;Json::Value root;ifstream is("test.json", ios::binary);  //打开文件,以二进制方式打开文件if (!is.is_open())               //检查文件打开情况cout << "open file failed" << endl;if (reader.parse(is, root)) {//读取根节点信息string group_name = root["Group Name"].asString();int number = root["Number"].asInt();cout << "Group Name: " << group_name << endl;cout << "Number: " << number << endl;//读取子节点信息int body[2];   //身高、体重/********注意遍历json数组的时候要使用unsigned int的变量********/body[0] = root["Students"]["Zhangsan"][(unsigned int)0].asInt();     body[1] = root["Students"]["Zhangsan"][(unsigned int)1].asInt();cout << "Zhangsan height:" << body[0] << " weight: " << body[1] << endl;body[0] = root["Students"]["Lisi"][(unsigned int)0].asInt();body[1] = root["Students"]["Lisi"][(unsigned int)1].asInt();cout << "Lisi height:" << body[0] << " weight: " << body[1] << endl;}is.close();return 0;
}

最后输出的结果如下图所示:

四、xml和json文件对比

1、xml如下:

2、如何用json来写此文件

#include <iostream>
#include <fstream>
#include <json/json.h>using namespace std;int main() {//根节点Json::Value root;//若直接使用“=”进行赋值,则默认该变量:为一个数或字符串root["CTHost Version"] = "1.00";root["LastModifyTime"] = "2024.11.14 17:29 : 00"; //1.根节点"Group Name"和值"Togehter"//若使用“append”则默认该变量:为向量的形式//3.根节点"Students"和值{"Zhangsan":[180,70], "Lisi":[165,50]}//3.1 Map形式root["Options"]["DeviceName"].append("AD90");root["Options"]["AutoConnectEngine"].append(1);root["Options"]["EngineTimeout"].append(60);root["Options"]["RemoteDir"].append("C:\\Host\\Config\\HOST alarm\\");root["Options"]["EngineIP"].append("127.0.0.1");//点root["TypePointCount"] = 2;root["TypePoint0"]["Type"] = "0";root["TypePoint0"]["PsTypePoint"]["PsType"]["IsValid"] = 0;root["TypePoint0"]["PsTypePoint"]["PsType"]["IsCompareWith1"] = 0;root["TypePoint0"]["PsTypePoint"]["PsType"]["Name"] = "OtPoint";root["TypePoint0"]["PsTypePoint"]["PsType"]["Code"] = "OTP";root["TypePoint0"]["PsTypePoint"]["PsGrade0"]["CountEnable"] = 0;root["TypePoint0"]["PsTypePoint"]["PsGrade0"]["CountMin"] = 0;root["TypePoint0"]["PsTypePoint"]["PsGrade0"]["CountMinCountMax"] = 0;root["TypePoint0"]["PsTypePoint"]["PsGrade1"]["CountEnable"] = 1;root["TypePoint0"]["PsTypePoint"]["PsGrade1"]["CountMin"] = 0;root["TypePoint0"]["PsTypePoint"]["PsGrade1"]["CountMinCountMax"] = 1;root["TypePoint1"]["Type"] = "0";root["TypePoint1"]["PsTypePoint"]["PsType"]["IsValid"] = 0;root["TypePoint1"]["PsTypePoint"]["PsType"]["IsCompareWith1"] = 0;root["TypePoint1"]["PsTypePoint"]["PsType"]["Name"] = "OtPoint";root["TypePoint1"]["PsTypePoint"]["PsType"]["Code"] = "OTP";root["TypePoint1"]["PsTypePoint"]["PsGrade0"]["CountEnable"] = 0;root["TypePoint1"]["PsTypePoint"]["PsGrade0"]["CountMin"] = 0;root["TypePoint1"]["PsTypePoint"]["PsGrade0"]["CountMinCountMax"] = 0;root["TypePoint1"]["PsTypePoint"]["PsGrade1"]["CountEnable"] = 1;root["TypePoint1"]["PsTypePoint"]["PsGrade1"]["CountMin"] = 0;root["TypePoint1"]["PsTypePoint"]["PsGrade1"]["CountMinCountMax"] = 1;//线root["TypeLineCount"] = 2;root["TypeLine0"]["Type"] = "0";root["TypeLine0"]["TypeLine"]["PsType"]["IsValid"] = 0;root["TypeLine0"]["TypeLine"]["PsType"]["IsCompareWith1"] = 0;root["TypeLine0"]["TypeLine"]["PsType"]["Name"] = "OtLine";root["TypeLine0"]["TypeLine"]["PsType"]["Code"] = "OTEP";root["TypeLine0"]["TypeLine"]["PsGrade0"]["CountEnable"] = 0;root["TypeLine0"]["TypeLine"]["PsGrade0"]["CountMin"] = 0;root["TypeLine0"]["TypeLine"]["PsGrade0"]["CountMinCountMax"] = 0;root["TypeLine0"]["TypeLine"]["PsGrade1"]["CountEnable"] = 1;root["TypeLine0"]["TypeLine"]["PsGrade1"]["CountMin"] = 0;root["TypeLine0"]["TypeLine"]["PsGrade1"]["CountMinCountMax"] = 1;root["TypeLine1"]["Type"] = "0";root["TypeLine1"]["TypeLine"]["PsType"]["IsValid"] = 0;root["TypeLine1"]["TypeLine"]["PsType"]["IsCompareWith1"] = 0;root["TypeLine1"]["TypeLine"]["PsType"]["Name"] = "OtLine";root["TypeLine1"]["TypeLine"]["PsType"]["Code"] = "OTEP";root["TypeLine1"]["TypeLine"]["PsGrade0"]["CountEnable"] = 0;root["TypeLine1"]["TypeLine"]["PsGrade0"]["CountMin"] = 0;root["TypeLine1"]["TypeLine"]["PsGrade0"]["CountMinCountMax"] = 0;root["TypeLine1"]["TypeLine"]["PsGrade1"]["CountEnable"] = 1;root["TypeLine1"]["TypeLine"]["PsGrade1"]["CountMin"] = 0;root["TypeLine1"]["TypeLine"]["PsGrade1"]["CountMinCountMax"] = 1;3.2 父子节点形式//Json::Value student;//student["Zhangsan"].append(180);//student["Zhangsan"].append(70);//student["Lisi"].append(165);//student["Lisi"].append(50);//root["Students"] = student;//格式化输出到文件  ofstream os;             //实例化输出类os.open("Option.json", std::ios::out); //打开并指定文件以输出方式打开(往文件里写)if (!os.is_open())               //检查文件打开情况cout << "open file failed" << endl;Json::StyledWriter sw;      //定义格式化输出os << sw.write(root);       //输出到文件  os.close();                 //关闭文件return 0;
}

结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/473630.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7.揭秘C语言输入输出内幕:printf与scanf的深度剖析

揭秘C语言输入输出内幕&#xff1a;printf与scanf的深度剖析 C语言往期系列文章目录 往期回顾&#xff1a; VS 2022 社区版C语言的安装教程&#xff0c;不要再卡在下载0B/s啦C语言入门&#xff1a;解锁基础概念&#xff0c;动手实现首个C程序C语言概念之旅&#xff1a;解锁关…

XXL-JOB相关面试题

分布式任务调度-xxl-job 任务量大&#xff0c;分片执行 定义cron表达式灵活 定时任务失败了&#xff0c;重试和统计 xxl-job路由策略有哪些&#xff1f; 轮询 故障转移 分片广播:**广播触发对应的集群中所有机器执行一次任务,同时系统自动传递分片参数,**可以根据分片参数开发…

华东师范大学数学分析第五版PDF习题答案上册及下册

“数学分析”是数学专业最重要的一门基础课程&#xff0c;也是报考数学类专业硕士研究生的专业考试科目。为了帮助、指导广大读者学好这门课程&#xff0c;编者编写了与华东师范大学数学科学学院主编的《数学分析》(第五版)配套的辅导用书&#xff0c;以帮助读者加深对基本概念…

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk)

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk) 1.计算模型介绍 使用GARCH&#xff08;广义自回归条件异方差&#xff09;模型计算VaR&#xff08;风险价值&#xff09;时&#xff0c;方差法是一个常用的方法。GARCH模型能够捕捉到金融时间序列数据中的波…

基于YOLOv8深度学习的智慧课堂学生专注度检测系统(PyQt5界面+数据集+训练代码)

本研究提出了一种基于YOLOv8深度学习的智慧课堂学生专注度检测系统&#xff0c;旨在实现对课堂中学生专注度的实时分析与评估。随着智慧教育的快速发展&#xff0c;学生的课堂表现和专注度成为评估学习效果的重要因素之一。然而&#xff0c;传统的专注度评估方法往往依赖于主观…

如何在 Ubuntu 上安装 Emby 媒体服务器

Emby 是一个开源的媒体服务器解决方案&#xff0c;它能让你整理、流媒体播放和分享你的个人媒体收藏&#xff0c;包括电影、音乐、电视节目和照片。Emby 帮你集中多媒体内容&#xff0c;让你无论在家还是在外都能轻松访问。它还支持转码&#xff0c;让你能够播放各种格式的内容…

HarmonyOS 如何获取设备信息(系统、版本、网络连接状态)

文章目录 前言一、引入模块和基本设备信息的获取二、设备硬件和系统版本信息的获取三、获取安全相关的设备信息四、获取网络状态信息五、完整 Demo 代码1. 导入所需模块2. 获取设备基本信息代码解析 3. 检测网络连接状态4. 执行函数 总结 前言 HarmonyOS 提供了一个强大的 API…

ES6笔记

ES6 ECMAScript ECMA组织&#xff1a;脚本语言标准化国际组织 1.什么是ES6 ES的全称是&#xff1a;ECMAScript&#xff0c;它是ECMA国际标准化组织制定的一项脚本语言的标准规范 2015年6月&#xff1a;ES2015 2016年6月&#xff1a;ES2016 2017年6月&#xff1a;ES2017 2018年…

常用命令之LinuxOracleHivePython

1. 用户改密 passwd app_adm chage -l app_adm passwd -x 90 app_adm -> 执行操作后&#xff0c;app_adm用户的密码时间改为90天有效期--查看该euser用户过期信息使用chage命令 --chage的参数包括 ---m 密码可更改的最小天数。为零时代表任何时候都可以更改密码。 ---M 密码…

游戏如何应对内存修改

据观察&#xff0c;近年来游戏黑灰产攻击角度多样化趋势显著&#xff0c;主要面临工作室、定制注入挂、模拟点击挂、内存修改挂、破解版等多方面安全问题。 据FairGuard数据统计&#xff0c;在游戏面临的众多安全风险中&#xff0c;「内存修改」攻击占比约为13%&#xff0c;主…

STM32单片机设计防儿童人员误锁/滞留车内警报系统

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 近年来在车辆逐渐普及的情况下&#xff0c;由于家长的疏忽&#xff0c;将…

华为欧拉系统使用U盘制作引导安装华为欧拉操作系统

今天记录一下通过U盘来安装华为欧拉操作系统 华为欧拉操作系统是国产的一个类似于Centos的Linus系统 具体实现操作步骤&#xff1a; 先在官网下载欧拉系统镜像点击跳转到下载 准备好一个大于16g的U盘 &#xff0c;用于制作U盘启动 下载一个引导程序制作工具&#xff0c;我使用…

Excel单元格中自适应填充多图

实例需求&#xff1a;在Excel插入图片时&#xff0c;由于图片尺寸各不相同&#xff0c;如果希望多个图片填充指定单元格&#xff0c;依靠用户手工调整&#xff0c;不仅费时费力&#xff0c;而且很难实现完全填充。如下图中的产品图册&#xff0c;有三个图片&#xff0c;如下图所…

51单片机应用开发---LCD1602显示应用

实现目标 1、了解LCD1602液晶屏&#xff1b; 2、掌握驱动程序的编写&#xff1b; 3. 具体目标&#xff1a;在屏幕上显示字符。 一、LCD1206概述 1.1 定义 LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置…

问题分析与解决:Android开机卡动画问题分析

1. 问题背景及描述 在一个android设备的开发的项目中遇到了一个比较典型的问题:在主板贴片完成后,首次刷入androdi固件验证时,遇到了按键出发开机后,系统启动到android动画界阶段时一直循环卡在此阶段,无法进入桌面。如下如所示: 此问题在许多android项目的首次点亮阶段均…

nfs服务器--RHCE

一&#xff0c;简介 NFS&#xff08;Network File System&#xff0c;网络文件系统&#xff09;是FreeBSD支持的文件系统中的一种&#xff0c;它允许网络中的计 算机&#xff08;不同的计算机、不同的操作系统&#xff09;之间通过TCP/IP网络共享资源&#xff0c;主要在unix系…

黑马智慧商城项目学习笔记

目录 智慧商城项目创建项目调整初始化目录vant组件库vant按需导入和全部导入 项目中的vw适配路由设计配置登录页静态布局图形验证码功能request模块-axios封装api模块-封装图片验证码接口 Toast轻提示&#xff08;vant组件&#xff09;短信验证倒计时功能登录功能响应拦截器统一…

MySQL中将一个字符串字段按层级树状展开

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 需求1.分析2.实现3.思路刨析表结构和数据 需求 数据库中有个字段如下 如何将其转换为如下形式&#xff1a; 1.分析 1.他的层级个数是不确定的&#xff0c;也就是说有的有2层有的有5…

IDEA优雅debug

目录 引言一、断点分类&#x1f384;1.1 行断点1.2 方法断点1.3 属性断点1.4 异常断点1.5 条件断点1.6 源断点1.7 多线程断点1.8 Stream断点 二、调试动作✨三、Debug高级技巧&#x1f389;3.1 watch3.2 设置变量3.3 异常抛出3.4 监控JVM堆大小3.5 数组过滤和筛选 引言 使用ID…

springboot基于Web足球青训俱乐部管理后台系统开发(代码+数据库+LW)

摘 要 随着社会经济的快速发展&#xff0c;人们对足球俱乐部的需求日益增加&#xff0c;加快了足球健身俱乐部的发展&#xff0c;足球俱乐部管理工作日益繁忙&#xff0c;传统的管理方式已经无法满足足球俱乐部管理需求&#xff0c;因此&#xff0c;为了提高足球俱乐部管理效率…