利用 yaml-cpp 开源库读写 yaml 配置文件—— 读写部分

这篇具有很好参考价值的文章主要介绍了利用 yaml-cpp 开源库读写 yaml 配置文件—— 读写部分。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

YAML文件解析

Node

Node 是 yaml-cpp 中的核心概念,是最重要的数据结构,它用于存储解析后的 yaml 信息。
Node一共有以下几种type:
1)Null 空节点
2)Sequence 序列,类似于一个Vector,对应YAML格式中的数组
3)Map 类似标准库中的Map,对应YAML格式中的对象
4)Scalar 标量,对应YAML格式中的常量

生成 Node 的形式有很多种,loadFile() 是最常见的一种。
Node LoadFile(const std::string& filename) ,其中filename 就是yaml文件的路径。

有了 Node 之后,所有的信息都可以检索到。比如 name.
cout << “name:” << config[“name”].as() << endl;其中as()表示将解析的内容转换成 string 类型,也可以转换成其它类型。

读写yaml文件

假设配置文件config.yaml

config.yaml内容

name: frank
sex: male
age: 18
skills: 
  c++: 1
  java: 1
  android: 1
  python: 1

注意:yaml 中的内容,: 后面一定要加空格

test_yaml.cpp文件内容

#include <iostream>
#include "yaml-cpp/yaml.h"
#include <fstream>
using namespace std;
int main(int argc,char** argv)
{
    YAML::Node config;
    try{
         config = YAML::LoadFile("../config.yaml");
    } catch(YAML::BadFile &e) {
        std::cout<<"read error"<<std::endl;
        return -1;
    }
    
    cout << "Node type " << config.Type() << endl;
    cout << "skills type " << config["skills"].Type() << endl;
    
    cout << "name:" << config["name"].as<string>() << endl;
    cout << "sex:" << config["sex"].as<string>() << endl;
    cout << "age:" << config["age"].as<int>() << endl;
 
    //读取不存在的node值,报YAML::TypedBadConversion异常
    try{
        string label = config["label"].as<string>();
    }catch(YAML::TypedBadConversion<string> &e){
        std::cout<<"label node is NULL"<<std::endl;
    }//TypedBadConversion是模板类,读取什么类型的参数就传入什么类型
 
    cout << "skills c++:" << config["skills"]["c++"].as<int>() << endl;
    cout << "skills java:" << config["skills"]["java"].as<int>() << endl;
    cout << "skills android:" << config["skills"]["android"].as<int>() << endl;
    cout << "skills python:" << config["skills"]["python"].as<int>() << endl;
    //通过迭代的方式,访问 skills 下面的各个元素
    for(YAML::const_iterator it= config["skills"].begin(); it != config["skills"].end();++it)
    {
        cout << it->first.as<string>() << ":" << it->second.as<int>() << endl;
    }
 
    YAML::Node test1 = YAML::Load("[1,2,3,4]");
    cout << " Type: " << test1.Type() << endl;
 
    YAML::Node test2 = YAML::Load("1");
    cout << " Type: " << test2.Type() << endl;
 
    YAML::Node test3 = YAML::Load("{'id':1,'degree':'senior'}");
    cout << " Type: " << test3.Type() << endl;
    //将score 写入./testconfig.yaml
    ofstream fout("./testconfig.yaml");
    config["score"] = 99;//添加新元素
    fout << config;
    fout.close();
    return 0;
}

重要内容简单解释

1)Node
Node 是 yaml-cpp 中的核心概念,它用于存储解析后的 yaml 信息。
生成 Node 的形式有很多种, loadFile() 是最常见的一种。

Node LoadFile(const std::string& filename)

filename 就是配置文件的路径。
有了 Node 之后,所有的信息都可以检索到。

2)skills 的信息怎么读呢?

skills:  
  c++: 1
  java: 1
  android: 1
  python: 1

其实也非常简单

cout << "skills c++:" << config["skills"]["c++"].as<int>() << endl;
cout << "skills java:" << config["skills"]["java"].as<int>() << endl;
cout << "skills android:" << config["skills"]["android"].as<int>() << endl;
cout << "skills python:" << config["skills"]["python"].as<int>() << endl;

yaml-cpp 中也可以通过迭代的方式,访问 Node 中的内容
比如,访问 skills 下面的各个元素

for(YAML::const_iterator it= config["skills"].begin(); it != config["skills"].end();++it)
{
    cout << it->first.as<string>() << ":" << it->second.as<int>() << endl;
}

用 begin() 获取迭代器,用 end() 判断迭代器是否结束。

3)NodeType
yaml 支持 Scalar、List、Map 类型,yaml-cpp 通过 NodeType 定义了 Node 的可能类型。

namespace YAML {
struct NodeType {
  enum value { Undefined, Null, Scalar, Sequence, Map };
};
}

对应未定义、空、标量、序列、字典。

YAML::Node test1 = YAML::Load("[1,2,3,4]");
cout << " Type: " << test1.Type() << endl;

YAML::Node test2 = YAML::Load("1");
cout << " Type: " << test2.Type() << endl;

YAML::Node test3 = YAML::Load("{'id':1,'degree':'senior'}");
cout << " Type: " << test3.Type() << endl;

上面的代码是为了判断 NodeType。

结果如下:

Type: 3
Type: 2
Type: 4

分别对应 Sequence、Scalar、Map。

4)yaml-cpp 写配置文件
日常开发中,除了读取配置参数,我们经常需要保存参数,yaml-cpp也提供了相应的功能。

ofstream fout("./testconfig.yaml");
config["score"] = 99;
fout << config;
fout.close();

将读取的config,添加一个 score,然后保存。
运行代码后,发现 build 文件夹下多了 testconfig.xml 文件,score 也被添加进去。

name: frank
sex: male
age: 18
skills:
  c++: 1
  java: 1
  android: 1
  python: 1
score: 99

5)总结:
std::ifstream file(“config.yaml”);
YAML::Node node = YAML::Load(file);//读取来自test.yaml的node文件YAML
std::cout << node <<std::endl;
//或者
YAML::Node node_2 = YAML::LoadFile(“config.yaml”);//也可以这样读取文件
std::cout << node_2[“node_2”] <<std::endl;//可以直接用下标访问
for(auto it = node_2.begin(); it != node_2.end(); it++)
std::cout << it->first << it->second << std::endl;//也可以用迭代器访问

node的增改查删

#include <fstream>
#include <yaml-cpp/yaml.h>
#include <iostream>
#include <assert.h>
 
int main()
{
    YAML::Node node;  
    assert(node.IsNull());  //初始化的节点是Null类型
    node["key"] = "value";  
    //node.force_insert("key", "value");//这个操作和上面等价,但是它不会检查是否存在"key"键,不推荐使用
    if(node["mascot"])
        std::cout << node["mascot"].as<std::string>() << "\n";//单纯的查询操作不会增加一个key,当然上面的if不会执行
 
    node["number"] = 255;
    assert(node.IsMap());   //node是一个Map
    node["seq"].push_back("first element");
    node["seq"].push_back("second element");//node的seq下是Sequence类型,有两个参数
 
    YAML::Node node_2;  
    node_2.push_back("first_item");//如果不给node_2键值对,它是一个sequence类型
    node_2.push_back("second_item");
    node_2.push_back("third_item");
    std::vector<int> v = {1,3,5,7,9};//给node_2插入了一个Sequence
    node_2.push_back(v);
    assert(node_2.IsSequence());//node_2仍然是一个Sequence
 
    assert(node_2[0].as<std::string>() == "first item");
    //对于Sequence类型,你可以使用它的下标来访问
    //注意这里as<T>是一个模板转换,node_2[0]的type是NodeType::Scalar
    auto it = node_2.begin();
    for(; it != node_2.end(); it++)
        std::cout << *(it) << std::endl;
    //当然,可以用迭代器来访问
    //它们的类型分别是NodeType::Scalar,NodeType::Scalar,NodeType::Scalar,NodeType::Sequence
    //取值时记得使用as进行模板转换
    node_2["key"] = "value";
    assert(node_2.IsMap());//一旦node_2接收到键值对,它转变为Map类型
    assert(node_2[0].as<std::string>() == "first item");//此时,Sequence时的下标变为它的key值
    node["node_2"] = node_2;//将node_2作为node的一个子项
    node["pointer_to_first_element"] = node["seq"][0];//也可以给已有的node设置一个别名,类似于一个指针
    assert(node["pointer_to_first_element"].as<std::string>() == "first element");//可以通过这个指针访问那个node
 
    //node.remove(node["seq"][0]);//可以通过指定一个node来删除它
    //node.remove("pointer_to_first_element");//也可以通过指定key来删除它
	std::cout << node << endl;
}

最后cout的结果如下:

key: value
number: 255
seq:
  - first element
  - second element
node_2:
  0: first item
  1: second_item
  2: third_item
  3:
    - 1
    - 3
    - 5
    - 7
    - 9
  key: value

注:如有侵权,请联系删除!文章来源地址https://www.toymoban.com/news/detail-497536.html

到了这里,关于利用 yaml-cpp 开源库读写 yaml 配置文件—— 读写部分的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • API Testing 一个基于 YAML 文件的开源接口测试工具

    目录 前言: 如何使用? 本地模式 服务端模式 文件格式 后续计划 API Testing 是一个基于 YAML 文件的开源接口测试工具,它可以帮助开发者快速地进行接口测试。 在选择工具时,可以从很多方面进行考量、对比,以下几点是该工具的特色或者优点:

    2024年02月16日
    浏览(33)
  • 【C++】开源:abseil-cpp基础组件库配置使用

    😏 ★,° :.☆( ̄▽ ̄)/$: .°★ 😏 这篇文章主要介绍abseil-cpp基础组件库配置使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路🥞 项目Github地址: https://github.com/abseil/abseil-cpp 官网:

    2024年02月13日
    浏览(36)
  • 【C++】开源:matplotlib-cpp静态图表库配置与使用

    😏 ★,° :.☆( ̄▽ ̄)/$: .°★ 😏 这篇文章主要介绍matplotlib-cpp图表库配置与使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路🥞 项目Github地址: https://github.com/lava/matplotlib-cpp matpl

    2024年02月14日
    浏览(31)
  • Yaml配置文件读取方法

    在日常的代码中,有一些值是配置文件中定义的,这些值可以根据用户的要求进行调整和改变。这往往会写在yaml格式的文件中。这样开放程序给用户时,就可以不必开放对应的源码,只开放yaml格式的配置文件即可。 将配置文件中的值读入程序也非常的简单。 我们先写一个简

    2024年02月11日
    浏览(26)
  • Keburnetes YAML配置文件管理

    Kubernetes 支持 YAML 和 JSON 格式管理资源对象 JSON 格式 :主要用于 api 接口之间消息的传递 YAML 格式 :用于配置和管理,YAML 是一种简洁的非标记性语言,内容格式人性化,较易读 YAML 语法格式 大小写敏感 使用缩进表示层级关系 不支持Tab键制表符缩进,只使用空格缩进 缩进的

    2024年02月14日
    浏览(25)
  • 一、SpringBoot基础[Yaml配置文件]

    解释:application.yaml用来替代application.properties文件,如果文件中有较多的配置时,使用Yaml明显方便了许多 application.properties文件格式: Yaml文件格式: 注意:写的时候冒号后面必须加空格否则没有任何效果 1.对象 2.数组 解释:下面的 - 就表示一个列表内容,有的则是 [] 表示

    2024年02月15日
    浏览(36)
  • java利用缓冲区及流式对大文件进行高效读写

    当处理大文件时,使用适当的技术和方法可以提高读写性能和效率。下面是一些针对大文件读写的示例说明: 字符流 缓冲区及分块读写  BufferedInputStream 和 BufferedOutputStream 大文件读取: try (FileInputStream fis = new FileInputStream(\\\"largefile.txt\\\");      BufferedInputStream bis = new BufferedInp

    2024年02月07日
    浏览(31)
  • springboot篇---配置文件yaml篇2

    1.语法结构分类: application.properties 语法结构 :key=value application.yml 语法结构 :key:空格 value **配置文件的作用 :**修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了  2.yaml概述 YAML是 “YAML Ain’t a Markup Language” (YAML不是一种标记语言)的递归缩写。

    2024年02月04日
    浏览(28)
  • yolov7简化yaml配置文件

    yolov7代码结构简单,效果还好,但是动辄超过70几个模块的配置文件对于想要对网络进行魔改的朋友还是不怎么友好的,使用最小的tiny也有77个模块 代码的整体结构简单,直接将ELAN结构化写成一个类就能像yolov5一样仅仅只有20几个模块,方便对网络结构进行魔改,看着也不容

    2024年02月09日
    浏览(25)
  • Docker Compose的yaml文件配置

    1、第一步是确认应使用的Compose版本 (1)去看官方文档,根据给出的文档选择对应的Compose版本 https://docs.docker.com/compose/compose-file/compose-file-v3/ Compose和Docker Engine版本对比截图: (2)使用以下命令查看自己的docker engine版本 效果图: (3)由图可知我的Docker Engine版本为20.10.17,根据官方

    2024年02月11日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包