在C++项目中使用YAML对数据进行有序化处理

本文介绍了在C++中使用yaml-cpp库在Visual Studio上进行安装和配置,并展示了如何进行YAML文件的增删查改操作。通过实例代码详细解释了如何包含头文件、链接库、写入和读取YAML数据,以及实现对YAML数据结构的查询和修改。
摘要由CSDN通过智能技术生成

YAML文件作为常用的序列化语言,通常用于数据的保存上。那么我们在c++中如何使用YAML语言呢?这篇博客将集中与c++项目在visual studio上yaml-cpp的安装以及使用YAML语言对数据进行增删查改上。

1、yaml-cpp在visual studio上的安装

我个人用的版本是visual studio 2022,首先在github上获取yaml-cpp项目,链接为

Gitee 极速下载/yaml-cpp

下载后使用cmake对yaml-cpp项目进行编译

  编译器和平台自己电脑上配置的版本,否则会报错。编译结果如下,提示编译成功。

然后我们在使用yaml-cpp时需要对文件路径进行配置

首先,对yaml头文件进行包含,选中yaml文件所在目录

 然后,对项目所需要的静态库文件(使用cmake生成)进行链接。在链接器常规子目录下找到附加库目录,设置为静态库文件所在的目录。

 在链接器输入子目录下找到附加依赖项,输入所需要的静态库文件

最后对动态库进行链接,将动态库文件yaml_cppd.dll文件移动至exe文件下

动态库链接的具体方式可参考:

 最后可实现对yaml文件的操作,测试代码如下:

#include "yaml-cpp/yaml.h"

#include <fstream>

int main()
{
	YAML::Node config;

	std::ofstream fout("file1.yml"); //< C++ stream 读取文件

	config["skills"]["eat"] = 10;	//< 修改格式1 
	config["name"] = "hening"; //< 修改格式2 

	fout << config;

	fout.close();

	return 0;
}

2、yaml数据的增删改查实现

yaml数据的数据格式主要分为三种:mapping(对象)、sequence(数组)、scalars(标量)

yaml数据结构参考博客:[C++]-yml库yaml-cpp简介_alwaysrun的博客-CSDN博客_yaml-cpp

yaml数据的增加:

void Add(std::string fileName, YAML::Node config)
{
	std::ofstream fout(fileName, std::ios::app);
	fout << std::endl << config;
	fout.close();
}

yaml数据的修改:

void Change(std::string fileName, YAML::Node config)
{
	std::ofstream fout(fileName);
	fout << std::endl << config;
	fout.close();
}

yaml数据的查询:

初始Node节点默认为map类型,当yaml读取数据时,根据节点的不同进行递归查询。本查询默认结果输出为字符串类型。

void Query(YAML::Node config)
{
	//enum value { Undefined, Null, Scalar, Sequence, Map };
	switch (config.Type() )
	{
	case 0:
	case 1:
		break;
	case 2: //scalar
	{
		std::cout << config.as<std::string>() << std::endl;
		break;
	}
	case 3: //sequence
	{
		std::cout << std::endl;
		for (auto it_1 : config)
		{
			std::cout << std::setw(3)<<"-";
			Query(it_1);
		}
		break;
	}
	case 4: //map
	{
		std::cout << std::endl;
		for (auto it_1 : config)
		{
			std::cout << std::setw(5) << it_1.first.as<std::string>() << ":";
			YAML::Node NodeNext = it_1.second;
			Query(NodeNext);
		}
		break;
	}
	default:
		break;
	}
}

yaml节点的删除:直接使用remove指令即可

config["skills"].remove("eat");

附上文件全部代码

#include "yaml-cpp/yaml.h"

#include <fstream>
#include <string>
#include <iostream>
#include <iomanip>

void Add(std::string fileName, YAML::Node config)
{
	std::ofstream fout(fileName, std::ios::app);
	fout << std::endl << config;
	fout.close();
}

void Change(std::string fileName, YAML::Node config)
{
	std::ofstream fout(fileName);
	fout << std::endl << config;
	fout.close();
}

void Query(YAML::Node config)
{
	//Node是一个类map结构
	//enum value { Undefined, Null, Scalar, Sequence, Map };
	switch (config.Type() )
	{
	case 0:
	case 1:
		break;
	case 2: //scalar
	{
		std::cout << config.as<std::string>() << std::endl;
		break;
	}
	case 3: //sequence
	{
		std::cout << std::endl;
		for (auto it_1 : config)
		{
			std::cout << std::setw(3)<<"-";
			Query(it_1);
		}
		break;
	}
	case 4: //map
	{
		std::cout << std::endl;
		for (auto it_1 : config)
		{
			std::cout << std::setw(5) << it_1.first.as<std::string>() << ":";
			YAML::Node NodeNext = it_1.second;
			Query(NodeNext);
		}
		break;
	}
	default:
		break;
	}
}

int main()
{
	YAML::Node config;
	std::string fileName = "file1.yml";

	//insert
	config["skills"]["eat"] = 10;	//< 修改格式1 
	config["name"] = "hening"; //< 修改格式2 
	config["hobby"].push_back("football");
	config["hobby"].push_back("basketball");

	Add(fileName, config);

	config.reset();

	//change
	config = YAML::LoadFile(fileName); 

	config["blood"] = 15;

	Change(fileName, config);

	//Query
	Query(config);

	//Delete
	config["skills"].remove("eat");

	system("pause");
	return 0;
}

将yaml文件与控制台查询结果做对比,可发现两者结果一致。

唯一的缺点是输出时,当node节点为map类型,无法有效区别层次,可添加循环嵌套实现。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值