yaml-cpp的实际使用注意事项

1、YAML语法

yaml类似于json、xml。是一种标记语法。

1.1、YAML语法基本规则

(1)关于大小写:

大小写敏感

(2)关于层级关系:

使用缩进表示层级关系,但缩进不允许使用tab,只允许空格。

缩进的空格数不重要,只要相同层级的元素左对齐即可

(3)支持注释:

注释以'#'开头

1.2、YAML 支持的数据类型:

(1)对象:

键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)

(2)数组:

一组按次序排列的值,又称为序列(sequence) / 列表(list)

(3)纯量(scalars):

单个的、不可再分的值

 

2、yaml-cpp使用

2.1、获取

yaml-cpp是一个用c++语言实现的github上的开源项目。可以自由的从github上进行下载克隆。

该项目用的管理工具是cmake,获取源码后根据源码中的readme进行编译(或交叉编译)即可,需要注意的是yaml-cpp是基于c++11开发的,因此要确保编译器支持c++11。

具体编译方法可以搜百度上有很多指导,这里不再赘述。

 

2.2、写代码

1、头文件

只需要包含一个头文件即可:#include "yaml.h"

 

2、加载yaml文件

try
{
    YAML::Node root_node = YAML::LoadFile("test.yaml");
}
catch(const YAML::Exception& e)
{
    // TODO:处理异常
}

LoadFile()方法再执行时,如果出现打开文件失败等情况会抛出异常,因此这里最好加上try catch。

YAML::Exception是YAML中自定义的异常类,该类继承自C++中标准的exception。因此,catch中也可以使用std::exception类,看个人习惯。

 

3、关于YAML::Node

通过YAML::LoadFile()方法,将整个yaml格式的文件加载并实例化一个YAML::Node类型的对象。
yaml-cpp中YAML::Node是核心,他把所有yaml中的对象全部抽象化为YAML::Node类型。

YAML::Node有三种类型:

  • Scalar

  • Sequence

  • Map

YAML::Node类提供了三个方法用于判断当前Node的类型:IsScalar()、IsSequence()、IsMap()

每实例化出一个Node对象之后都要首先判断一下该Node对象的类型是什么,确定好类型之后再根据不同类型的特点进行对该Node对象的值操作。

如果对Node对象进行了不符合其类型特点的操作之后,代码会抛出异常。因此,如果Node对象的类型是不确定的情况下进行值操作时,一定要加上try catch接收异常。

例如:

YAML::Node tmp_node_people = root_node["people"];

if (tmp_node_people.IsMap()) 
{
    //如果确定是Map,那么可以放心的使用[]操作符
    YAML::Node tmp_node_name = tmp_node_people["name"];
}
else if (tmp_node_people.IsScalar())
{
    //如果确定是Scalar,可以放心的使用as方法
    std::people_name = tmp_node_people.as();
    //但是需要注意的是,as<>中指定的类型如果是std::string不会有风险,因为一切都是字符串,转换没有问题,但是如果指定的是其他值,例如std::int,但实际yaml文件中该值是个字母,那么就会有异常抛出。因此,再使用as操作时,如果指定std::string之外的的类型时最好加上try catch。
}
else if (tmp_node_people.IsSequence())
{
    //如果确定是Sequence,那么可以放心的使用[]操作符,当然里面必须是整数格式的元素下标,否则会抛出异常。
    YAML::Node tmp_node_name = tmp_node_people[0];
}
else
{
    //TODO:处理未知类型(未知类型是无法操作的)
}

 

Scalar类型的访问:


YAML::Node tmp_node_age = root_node["age"];


int tmp_age = tmp_node_age.as(); //注意:这里如果确定此Scalar对象对应的值是int类型的可以直接操作,但如果不确定需要使用try catch以防抛出异常。

Map类型的访问:

// Map类型即为键值对,yaml-cpp中将Map类型的节点,使用pair类型进行遍历
for (YAML::const_iterator it = root_node.begin(); it != root_node.end(); ++it) 
{
    YAML::Node tmp_key_node = it->first;
    YAML::Node tmp_value_node = it->second;

    key = tmp_key_node.as();
    value = tmp_value_node(); //注意如果这里确定value是Scalar类型,是可以这样操作的,如果不确定,一定要先通过IsXXX()方法确定类型,然后操作。
}

 

Sequence类型的访问:


YAML::Node tmp_node_list = root_node["list"];

for (int i = 0; i < tmp_node.size(); i++)
{

    std::string tmp_meta = tmp_node_list[I].as(); //注意:这里如果确定Sequence中每个元素都是Scalar类型的,可以使用as()进行访问,否则需要使用IsXXX()先判断类型。
}

 

YAML::Exception

YAML::TypedBadConversion  //类型转换错误
YAML::BadFile  //文件访问错误
YAML::BadSubscript  //子类型错误(例如:Node对象是个Scalar但你确使用了[]操作符进行访问)
...

 

 

 

 

 

你可能感兴趣的:(c++,yaml,yamp-cpp)