YAML解析库:yaml-cpp

yaml-cpp

引言

基本信息

  • yaml:YAML是专门用来写配置文件的语言,非常简洁和强大,比json和xml格式要方便很多,更容易阅读
  • yaml-cpp:是一个开源的C++解析yaml配置文件的库,我们可以使用该库进行解析项目中的yaml文件

windows添加环境变量

  1. 右键点击此电脑,点击属性,选择高级系统设置(或者打开设置,进入系统选型卡,点击系统信息,然后点击高级系统设置),点击环境变量后

    image-20241009092956650

  2. 在用户变量中的双击Path,然后新建,将需要添加到环境变量中的地址放入,然后确定

    image-20241009093305287

安装准备

  1. 下载源码包

    git clone git@github.com:jbeder/yaml-cpp.git
    
  2. 进入yaml-cpp目录后,创建build目录并且进入

    # linux
    cd yaml-cpp
    mkdir build && cd build
    
    # windows
    cd yaml-cpp
    mkdir build
    cd build
    
  3. 将其编译成动态库或静态库来链接到项目中使用

  4. 安装cmake和编译工具

    • windows:进入Download CMake进行下载安装适合的cmke环境,点击w64devkit安装编译环境工具,然后将安装cmake和w64devkit的bin目录地址添加到环境变量中
    • Linux:使用命令行安装Moon’s CMake

注意:这里windows编译库的方法是用mingw的编译工具的,如果需要VS或者Ninja就去百度来查找进行编译

Windows编译库

  1. 进入到yaml-cpp目录下的build目录后用终端打开(右键文件夹)

  2. 执行以下命令:

    cmake .. -G “MinGW Makefiles”
    # 需要生成动态库执行以下命令
    cmake .. -G “MinGW Makefiles” -D BUILD_SHARED_LIBS=ON
    
    # 进行make生成
    make
    
    # 如果需要安装可以
    make install
    

Linux编译库

cd yaml-cpp
mkdir build && cd build

cmake .. && make
# 需要动态库
cmake .. -D BUILD_SHARED_LIBS=ON && make
# 需要安装
sudo make install

YAML语法

基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • '#'表示注释
  • 字符串默认不使用引号表示,如果字符串之中包含空格或特殊字符,需要放在引号之中
  • 单引号和双引号都可以使用,双引号不会对特殊字符转义
  • 单引号之中如果还有单引号,必须连续使用两个单引号转义
  • 字符串可以写成多行,从第二行开始,必须有一个单空格缩进,换行符会被转为空格
  • 映射写法为 key: value,冒号后需要带空格

标量(Scalars)单个的、不可再分的值(date、boolean、string、number、null、字符串、浮点数、时间、日期)

# 写法
k: v

对象(Map)键值对的集合(map、hash、set、object),又称为映射/哈希/字典

# 行内写法
k: {k1:v1,k2:v2,k3:v3}
# 或分层写法
k:
 k1: v1
 k2: v2
 k3: v3

数组(Sequence)一组按次序排列的值(array、list、queue)

# 行内写法
k: [v1,v2,v3]
# 或分层写法
k:
 - v1
 - v2
 - v3

引用

  • 可以通过引用另一个变量来设置value,使用${}引用变量

    # 定义变量
    test:
     p: 1
    
    test1: 1
    
    name: 
     p1: ${test.p}
     p2: ${test1}
    
  • 通过引用锚点&来设置值,用*来取锚点值,可以通过<<:将键值对一起引入

    # 设置锚点
    test: &test-c
     p: 1
    
    name:
     <<: *test-c
    
  • 通过使用锚点&来设置键,用*来取锚点值

    test: 
     p1: &test-p1 pp1
     p2: &test-p2 pp2
     
    name:
     *test-p1: 1
     *test-p2: 2
    

yaml-cpp使用

引入头文件

#include "yaml-cpp/yaml.h"

Node

  • 概念:Node 是 yaml-cpp 中的核心概念,是最重要的数据结构,它用于存储解析后的yaml信息
  • type未定义(Undefined)、空节点(Null)、标量(Scalar)、数组(Sequence)、对象(Map)
namespace YAML {
  struct NodeType {
    enum value { Undefined, Null, Scalar, Sequence, Map };
  };
}

//定义节点
YAML::Node node; 	//初始化为null类型

检查节点类型:

//示例:
if (config["key"].IsScalar()) {
    // 处理标量
} else if (config["key"].IsSequence()) {
    // 处理序列
} else if (config["key"].IsMap()) {
    // 处理映射
}

赋值:

//定义节点
YAML::Node node;
//标量赋值
node["key"]="value";

//对象赋值
YAML::Node node1;
node1["key"]["p1"]=1;
node1["key"]["p2"]=2;
//对象中插入值
node1["seq"].push_back("1");

//数组赋值
YAML::Node node2;
node2.push_back("1");
node2.push_back("2");
//数组转变map
node2["key"]="value";

//插入数组
YAML::Node node3;
std::vector<int> v = {1,2,3,4};
node3.push_back(v);

//将node2和node3作为node的子项
node["node2"]=node2;
node["node3"]=node3;

//输出查看
std::cout<<node<<std::endl;

取值使用.as()来将值以type类型取出

//取值模板
type value=<Node name>["key"].as<type>();
type value=<Node name>["key"]["key1"].as<type>();

//示例:
//标量取值
std::string ip=config["ip"].as<std::string>();

//对象取值
int port=config["settings"]["port"].as<int>();

删除:使用remove方法进行删除指定节点中的键和指定键

node.remove("key");	//通过指定键删除
node.remove(node["seq"]["0"]);	//删除指定节点中的键

迭代:使用YAML::const_iterator迭代器

  • 解析数组

    //YAML的迭代器为YAML::const_iterator
    for(YAML::const_iterator it=config["key"].begin();it!=config["items"].end();++it){
        std::cout<<it->as<type>()<<std::endl;
    }
    
    //或者
    for(auto it=config["key"].begin();it!=config["items"].end();++it){
        std::cout<<it->as<type>()<<std::endl;
    }
    
    //或者
    for(auto const &it:config["items"]){
        std::cout<<it.as<std::string>()<<std::endl;
    }
    
  • 解析对象

    //YAML的迭代器为YAML::const_iterator
    for(YAML::const_iterator it=config["key"].begin();it!=config["items"].end();++it){
        std::string key = it->first.as<std::string>();
      	std::string value = it->second.as<std::string>();
      	std::cout << key << ": " << value << std::endl;
    }
    
    //或者
    for(auto it=config["key"].begin();it!=config["items"].end();++it){
        std::string key = it->first.as<std::string>();
      	std::string value = it->second.as<std::string>();
      	std::cout << key << ": " << value << std::endl;
    }
    
    //或者
    for(auto const &it:config["items"]){
        std::string key = it.first.as<std::string>();
      	std::string value = it.second.as<std::string>();
      	std::cout << key << ": " << value << std::endl;
    }
    

读取yaml文件使用Load或者LoadFile方法

std::ifstream file("config.yml");
YAML::Node node = YAML::Load(file);//读取来自config.yml的node文件
std::cout << node <<std::endl;
//或者
YAML::Node node_2 = YAML::LoadFile("config.yml");//也可以这样读取文件

保存yaml文件/输出

YAML::Node out;
std::ofstream fout("output.yaml");
//更改out里的数据
...
fout << out;
fout.close();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Moon2144

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

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

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

打赏作者

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

抵扣说明:

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

余额充值