【C++】C++操作jsoncpp(写、读、解析)+jsoncpp从0到1配置步骤

前言

json文件是比较轻量级的文件,格式简单,使用方便。用来存放信息相比其他方式有自己得天独厚的优势。

今天给大家分享的是如何利用C++来操作json文件。

如果你知道如何使用jsoncpp类库,可以不用看附录,如果第一次使用,请先到最后,将环境配置好,再进行操作。

01、json文件介绍

1.1、json简介

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率

1.2、json优势

常用存储数据的方式有很多,比如利用txt文件,xml文件,word文件,Excel文件,如果我们要求比较高,还可以使用数据库文件(MySQL/SQL Server/Oracle)。

  1. 相对于txt,word来说,json格式更加明确,获取重要信息非常方便。
  2. 相对于xml来说,json格式更加简洁,存储同样的文件,花费的内存更小。
  3. 相对于Excel来说,json更适合存储字符类文件。Excel相当于比较简单的数据库了。
  4. 相对于数据库来说,json更加方便,数据库我们还需要做一些设置,安装一些软件。json可以直接使用。

02、C++ 操作 jsoncpp(读、写、解析)

程序中所有函数的调用我都写在最后的Main.cpp中,下面出现的声明、定义都是OperationJson.h与OperationJson.cpp中的内容的拆分版本。

2.1、解析(nor)

解析之前,我们先定义一个简单的字符串(中间串),替代json格式的解析,如下:

/* Json格式 */
{
	"name":"Cain",
	"age":23,
	"sex":"man"
}
/* 字符串格式 */
const char* str = "{\
					\"name\":\"Cain\",\
					\"age\":23,\
					\"sex\":\"man\"\
					}";

字符串格式解析:(大佬可以自行跳过,新手我说明一下)

  1. "{\:此处的\意思是下一行接着这一行开始,并没有结束。
  2. \"name\”:此处的\",代表字符串的转义,C语言基础,忘记了可以回顾下。
  3. json中的所有值格式都是通过首、尾来标识的,什么意思呢,就是说,如果,你在\"age\":23此处这么写,他就是一个in类型,待会儿就会用asIng(),解析,内部也是如此,如果你是以\"age\":\"23\"
    这一种方式写的,内部识别首尾为“”,使用asString()进行解析,而你要的是asInt(),则会出现断言错误,因为jsoncpp中错误的处理方式都是断言。这里是我踩的坑,我说明一下,分享给大家,后面的例子中,涉及我不会再重复提出。

Kernel Code:

#include <string>

//声明
void AnalysisJsonString(string strJsonText);

//定义  (实际我是以类的形式对这三种写法写的代码,这只是我拆分出来方便大家看)
void OperJson::AnalysisJsonString(string strJsonText)
{
	string name,sex;
	int age;
	
	Json::Reader reader;
	Json::Value value;

	//从字符串中读取数据
	if(reader.parse(strJsonText,value))
	{
		name = value["name"].asString();
		age = value["age"].asInt();
		sex = value["sex"].asString();
	}

	//输出格式大家自定义就好了,我这么写完全是为了输出好看
	cout << "{ " << endl;
	cout << "   " << "\"name\":" << " \" " << name << " \" " <<endl;
	cout << "   " << "\"age\":" << age<<endl;
	cout << "   " << "\"sex\":" << " \" " << sex<< " \" " <<endl;
	cout << "} " << endl;
}

Run Image:
在这里插入图片描述

2.2、解析(pro)

还是先定义一个字符串(复杂一点),如下:

//Json格式
{
	"name":"Cain",
	"major":
	[
	{ "computer" : "C"},
	{ "computer" : "C++"},
	{ "computer" : "Python"},
	{ "computer" : "Go"}
	]
}

//字符串格式
const char* buf = "{\
					\"name\":\"Cain\",\
					\"major"\:[{\
					\"computer\":\"C\"},\
					\"computer\":\"C++\"},\
					\"computer\":\"Python\"},\
					\"computer\":\"Go\"}\
					]}";

字符串解析(略)。

Kernel Code:

//声明
void AnalysisJsonStringPro(string strJsonText);

//定义
void OperJson::AnalysisJsonStringPro(string strJsonText)
{
	string name;
	string major;
	vector<string> vec;  //包含vector头文件
	
	Json::Reader reader;
	Json::Value value;
	Json::Value root;
	
	if(reader.parse(strJsonText,root))
	{
		name = root["name"].asString();
		value = root["major"];
		cout << "name: " << name << endl;
		
		for(int i = 0; i < root["major"].size(); i++)
		{
			major = value[i]["computer"].asString();
			vec.push_back(major);
		}
	}
	//区间迭代(C++ 11)
	for(string buf : vec)
	{
		cout << "major: " << buf << endl;
	}
}

关于区间迭代,感兴趣可以查看我以前写的一篇STL博客 【STL】标准容器-vector

Run Image:
在这里插入图片描述

2.3、写Json文件

读写Json文件我就直接上代码+测试图,感兴趣,大家可以拿去自己测试,程序肯定是OK的。

Kernel Code:

//声明
void WriteFileJson(string filePath);

//定义
void OperJson::WriteFileJson(string filePath)
{
	//写入下列指定内容
	const char* str = "{\
						\"name\":\"Cain\",\
						\"sex\":\"man\",\
						\"age\":23,\
						\"hobby\":[\"Run\",\"Sing\",\"Dance\"],\
						\"major\":[\
						{\"subject1\":\"C++\"},\
						{\"subject2\":\"Jave\"},\
						{\"subject3\":\"Go\"}]\
						}";

	Json::Value root;
	root["name"] = Json::Value("Cain");
	root["sex"] = Json::Value("man");
	root["age"] = Json::Value(23);
	
	//数组形式
	root["hobby"].append("Run");
	root["hobby"].append("Sing");
	root["hobby"].append("Dance");
	
	Json::Value Sub;
	//子节点属性
	Sub["subject1"] = Json::Value("C++");
	Sub["subject2"] = Json::Value("Java");
	Sub["subject3"] = Json::Value("Go");

	//将子节点内容挂到父节点(root)上
	root["major"] = Json::Value(Sub);

	/* 测试内容:会在屏幕输出 */
	cout << "styledwriter: " << endl;
	Json::StyledWriter sw;
	cout << sw.write(root) << endl;

	//将内容输入到指定的文件
	ofstream os;
	os.open(filePath,ios::out || iios::app);
	if(!os.is_open())
	{
		cout << "Error: can not find or create the file which named " << filePath << endl;
	}
	else
	{
		cout << "successful: file write is success! " << endl;
	}

	os << sw.write(root);
	os.close();
}

Run Image:
在这里插入图片描述
在这里插入图片描述

2.4、读Json文件

Kernel Code:

//声明
void ReadFileJson(string filePath);

//定义
void OperJson::ReadFileJson(string filePath)
{
	Json::Reader reader;
	Json::Value root;
	
	//读取文件中的数据
	ifstream in;
	in.open(filePath,ios::in || ios:: binary);
	if(!in.is_open())
	{
		cout << "Error: open file is failed! " << endl;
	}
	else
	{
		cout << "Successful: file read is success! " << endl;
	}
	
	Json::StyledWriter sw;

	if(reader.parse(in,root))
	{
		//读取节点信息
		string name = root["name"].asString();
		int age = root["age"].asInt();
		string sex = root["sex"].asString();
		
		for(int i = 0; i < root["hobby"].size(); i++)
		{
			string str = root["hobby"][i].asString();
		}

		Json::Value tmp;
		tmp = root["major"];

		sw write(root);
		cout << sw.write(root) << endl;
	}
	else
	{
		cout << "Error: parse is error! " << endl;
	}
}

Run Image:
在这里插入图片描述

2.5、Main.cpp
#include <iostream>
#include <string>
#include "OperationJson.h"

using namespace std;

/* 定义两个宏,使读写json文件区分开来,当然也可以只用一个,读写都用一个,最简单 */
#define READ_JSONFILE_PATH "C:\\Users\\M\\Desktop\\read.json"
#define WRITE_JSONFILE_PATH "C:\\Users\\M\\Desktop\\write.json"

int maiin(int argc,char* argv[])
{
	const char* str = "{\
					\"name\":\"Cain\",\
					\"age\":23,\
					\"sex\":\"man\"\
					}";
					
	const char* buf = "{\
					\"name\":\"Cain\",\
					\"major"\:[{\
					\"computer\":\"C\"},\
					\"computer\":\"C++\"},\
					\"computer\":\"Python\"},\
					\"computer\":\"Go\"}\
					]}";

	OperJson json;

	//简单解析Json(字符串形式)
	json.AnalysisJsonString(str);
	//升级版解析Json(字符串形式)
	json.AnalysisJsonString(buf);
	//写Json文件
	json.WriteFileJson(WRITE_JSONFILE_PATH);
	//读Json文件
	json.ReadFileJson(READ_JSONFILE_PATH);

	system("pause");
	return 0;
}

Ps:如果按照我上面这样写两个宏,那么json文件要么是从外部创建,要么就是先写再重命名。因为实际我们使用json文件的时候都不是同名的,当然测试使用同名肯定是更简单,大家自行决定。
上面涉及到iostream.h头文件中的读写方法,这是C++中的方法,同C原理相同,可以网上了解一下。
要注意的是:
1.如果要写入的文件不存在,会自动创建该文件;
2.如果文件存在,写入过程不会覆盖文件中原有数据,而是将新数据写在原有数据后面。

03、Jsoncpp库配置从0到1

JsonCpp是一个基于C++语言的开源库,用于C++程序的Json数据的读写操作。

3.1、Jsoncpp库下载

Jsoncpp库github地址:https://github.com/open-source-parsers/jsoncpp
Jsoncpp文档地址:http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html
jsoncpp官网库地址:https://sourceforge.net/projects/jsoncpp/

我使用的是第三个链接下载的库包,下面我配置也是如此,以第三个为例,核心步骤都一样,不用担心下载地址的不同而无法使用。

3.2、配置步骤
  • 解压并转移
    首先将库解压,将下面的两个文件夹复制到你创建的项目下面,如下图:
    在这里插入图片描述
    在这里插入图片描述

  • 项目配置
    首先进入你的VS项目,依次点击工具栏上的项目——>属性,然后按照下图步骤操作:

在这里插入图片描述

  • Jsoncpp头文件使用

    将刚才的include文件夹下的所有文件和src下的json文件夹下的所有文件一起拷贝到项目目录下的新建筛选项(直接在VS界面添加、新建筛选项即可)下,如下图在这里插入图片描述
    在这里插入图片描述

配置到此处,项目里就可以使用Jsoncpp库了。

04、附录

关于iostream.h的使用,就是写文件的时候如果没有自己手动创建文件,按照上面的代码是无法创建的,必须在ofstream os(文件路径);,这样就可以创建了,这里说明一下,读文件是不需要的,只需要给对路径文件就可以了。

jsoncpp配置所连接的github地址参考了下面文章中的引用:
https://www.cnblogs.com/esCharacter/p/7657676.html

版权声明:创作不易,转载请注明出处!

  • 9
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
### 回答1: C++和MFC结合使用JsonCpp库可以很方便地处理JSON数据。JsonCpp是开源的C++库,提供了用于取、入和操作JSON数据的方法和。 首先,使用JsonCpp库,我们需要将JsonCpp的头文件和源文件包含到项目中,并链接相应的库文件。 然后,我们可以使用JsonCpp库提供的方法来解析和生成JSON数据。例如,如果我们有一个JSON字符串,我们可以使用Json::Reader解析它: ``` Json::Value root; Json::Reader reader; std::string jsonString = "{\"name\":\"John\",\"age\":30}"; // 假设我们有一个JSON字符串 bool parsingSuccess = reader.parse(jsonString, root); if (parsingSuccess) { std::string name = root["name"].asString(); // 获取"name"字段的值 int age = root["age"].asInt(); // 获取"age"字段的值 // 进一步处理... } ``` 同样,如果我们想生成一个JSON字符串,我们可以使用Json::Value来构建JSON对象: ``` Json::Value root; root["name"] = "John"; root["age"] = 30; // 进一步添加其他字段... Json::FastWriter writer; std::string jsonString = writer.write(root); // 输出结果:{"name":"John","age":30} ``` 除了取和生成JSON数据之外,JsonCpp还提供了其他一些功能,如检查JSON数据是否有效、遍历JSON对象等。 总之,C++和MFC结合使用JsonCpp库可以方便地处理JSON数据。我们可以使用JsonCpp提供的方法来解析和生成JSON数据,从而实现JSON数据的取和操作。 ### 回答2: 在C++/MFC中使用JSONcpp库可以方便地进行JSON数据的解析和生成。JSONcpp是一个开源的C++库,提供了一套API供开发人员操作JSON数据。 首先,在使用JSONcpp之前,需要将其库文件添加到项目中。可以从JSONcpp的官方网站或其他途径下载JSONcpp的源代码,并将其编译为静态库或动态库文件。 接下来,可以通过以下步骤C++/MFC中使用JSONcpp: 1. 引入JSONcpp的头文件: ```cpp #include <json/json.h> ``` 2. 创建一个Json::Value对象,用于存储解析后的JSON数据或将数据转换为JSON格式: ```cpp Json::Value jsonValue; ``` 3. 解析JSON数据: ```cpp Json::CharReaderBuilder jsonBuilder; std::string jsonStr = "{\"name\":\"John\", \"age\":30, \"city\":\"New York\"}"; std::istringstream jsonStream(jsonStr); std::string jsonErrs; if (Json::parseFromStream(jsonBuilder, jsonStream, &jsonValue, &jsonErrs)) { // 解析成功,可以通过jsonValue对象访问解析后的数据 } else { // 解析失败,处理错误 } ``` 4. 访问解析后的JSON数据: ```cpp std::string name = jsonValue["name"].asString(); int age = jsonValue["age"].asInt(); std::string city = jsonValue["city"].asString(); ``` 5. 生成JSON数据: ```cpp jsonValue["name"] = "John"; jsonValue["age"] = 30; jsonValue["city"] = "New York"; std::ostringstream jsonStream; Json::StreamWriterBuilder jsonWriter; std::unique_ptr<Json::StreamWriter> writer(jsonWriter.newStreamWriter()); writer->write(jsonValue, &jsonStream); std::string jsonStr = jsonStream.str(); ``` 通过以上步骤,可以在C++/MFC中很方便地使用JSONcpp进行JSON数据的解析和生成。在实际应用中,可以根据需要,结合其他功能,灵活地处理JSON数据。 ### 回答3: 在使用MFC开发项目时,我们可以通过Jsoncpp库来处理JSON数据。Jsoncpp是一个开源的C++库,提供了一套简单易用的API来取、解析、生成和操作JSON数据。 首先,我们需要将Jsoncpp库添加到MFC项目中。可以从官方网站上下载到源代码,然后将其编译成静态链接库或动态链接库,再将其导入到MFC项目中。 接下来,我们可以使用Jsoncpp提供的API来解析JSON数据。可以使用Json::Value对象来表示JSON数据,并通过Json::Reader来JSON数据并解析Json::Value对象。例如,可以使用以下代码来解析一个包含JSON数据的字符串: ```cpp #include <json/json.h> #include <iostream> int main() { std::string jsonData = "{\"name\":\"John\",\"age\":30}"; Json::Value root; Json::Reader reader; bool success = reader.parse(jsonData, root); if (success) { std::string name = root["name"].asString(); int age = root["age"].asInt(); std::cout << "Name: " << name << std::endl; std::cout << "Age: " << age << std::endl; } else { std::cout << "Failed to parse JSON!" << std::endl; } return 0; } ``` 上述代码将会输出以下结果: ``` Name: John Age: 30 ``` 除了解析JSON数据,我们还可以使用Jsoncpp生成JSON数据。可以使用Json::Value对象来表示生成的JSON数据,并通过Json::FastWriter或Json::StyledWriter来将Json::Value对象转换为字符串。例如,可以使用以下代码来生成一个包含JSON数据的字符串: ```cpp #include <json/json.h> #include <iostream> int main() { Json::Value root; root["name"] = "John"; root["age"] = 30; Json::FastWriter writer; std::string jsonData = writer.write(root); std::cout << "JSON Data: " << jsonData << std::endl; return 0; } ``` 上述代码将会输出以下结果: ``` JSON Data: {"name":"John","age":30} ``` 除了解析和生成JSON数据,Jsoncpp还提供了其他一些API来操作JSON数据,例如增加、修改、删除和查找JSON对象和数组中的元素。 总之,使用Jsoncpp库可以很方便地在MFC项目中处理JSON数据。无论是解析JSON数据还是生成JSON数据,Jsoncpp都提供了简单易用的API来满足我们的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cain Xcy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值