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

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.kler.cn/a/395635.html

相关文章:

  • 学习threejs,使用TWEEN插件实现动画
  • 昆明华厦眼科医院举办中外专家眼科技术研讨会
  • QT_CONFIG宏使用
  • 在 Oracle Linux 8.9 上安装Oracle Database 23ai 23.5
  • react 受控组件和非受控组件
  • 基于微信小程序的公务员考试学习平台的设计与实现,LW+源码+讲解
  • 【Java Web】MVC与分层开发
  • Gin路由深入
  • STM32芯片EXIT外部中断的配置与原理
  • FPGA 第6讲 简单组合逻辑多路选择器
  • Datawhale模型压缩技术Task2之模型剪枝
  • 基于Java Springboot旅游信息推荐系统
  • 全面解读 USB Key:定义、使用场景、加密技术及 Java 实现
  • linux之调度管理(5)-实时调度器
  • 【计算机网络】TCP协议特点3
  • 通过地址获取LONG和LAT并且存入csv
  • ubuntu, 安装部署comfyui,记录1:
  • Nginx在Windows上和Linux上(Docker启动)分别配置基本身份认证示例
  • 计算机毕业设计Python+CNN卷积神经网络股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI
  • 千益畅行,共享旅游卡市场乱象解析与未来展望
  • Python3中str和bytes
  • STM32串口——5个串口的使用方法
  • selenium元素定位---元素点击交互异常解决方法
  • 0x00基础算法 -- 0x05 排序
  • Modern Effective C++:item 1 理解模板类型推导
  • Spring Boot 中使用 @Transactional 注解配置事务管理