yaml 使用自定义类型读取和写回文件 .as 和emitter 以及随机出现解析失败警告

一.意义
 yaml对于内容有类型判断,也可以通过!!进行指定类型,所以这给读取自定义结构类型的yaml读取提供了可以,而不是在yaml 0.5以后的版本中还需要重载一大堆的>>符号

二.参考资料
yaml-cpp官网
https://github.com/jbeder/yaml-cpp/wiki/Tutorial

node.Type()
-Null
-Scalar
-Sequence
-map
-undefined

三.读取
重载yaml命名空间里面的decode函数

struct Vec3 { double x, y, z;};
namespace YAML {
template<>
struct convert {
  static bool decode(const Node& node, Vec3& rhs) {
    if(!node.IsSequence() || node.size() != 3) {
      return false;
    }
    rhs.x = node[0].as();
    rhs.y = node[1].as();
    rhs.z = node[2].as();
    return true;
  }
};
}
YAML::Node node = YAML::Load("start: [1, 3, 0]");
Vec3 v = node["start"].as();
node["end"] = Vec3(2, -1, 0);


来一个复杂一点的
yaml数据为:

-name:marry
 id:10
 sex:female
 workday:[1,2,5,6]

-name:dave
 id:11
 sex:male
 workday:[2,3,4,5]

定义结构体为

struct employee
{
 string name;
 int id;
 string sex;
 struct workDay{double one,two,three,four};
}

这个时候重载decode函数为   
//decode

//其实decode函数就是告诉yaml怎么把yaml读取后的数组的内容和自定义数据类型进行复制
static bool decode(const Node& node, employee& subdata) {//一个"-"表示一个node

    subdata.name = node[0].as();
    subdata.id = node[1].as();     //这个时候类型只能是int 否则也会解析失败
    subdata.sex = node[2].as(); //还可以在decode里面做内容的判断
    if(subdata.sex!="male"||subdata.sex!="female")
    return false;//函数最后return false会throw 一个exception 需要话在使用node.as的时候使用try catch去捕获异常
    subData.workDay.one=node[3][0].as();
    subData.workDay.two=node[3][1].as();
    subData.workDay.three=node[3][2].as();
    subData.workDay.four=node[3][3].as();
    return true;
}


//解析失败原因
1.访问了一个node数组为空的项
2.内容类型和指定as解析的不同,例如 id=ss这个时候就会报错了 as支持c++八大基本类型
3.和decode函数里面设定的条件不同 sex=man 这个时候也会throw一个exception
通过try catch 抓住yaml exception&e之后 可以通过e.what来显示集体是哪一行出了问题
//可以用node["name"]同样能够读取的到

四、写回


yaml-cpp 0.5之后就不在使用encode这个重载函数,而是使用了一个emiter对象,所以需要在使用写回yaml文件的类中声明emiter的<<为重载函数
一个emiter就相当是一个文件对象 同样的<<主要就是声明怎么把 自定义的类型数据和node建立一一对应的联系

struct employee
{
 string name;
 int id;
 string sex;
 struct workDay{double one,two,three,four};
}
YAML::Emitter& operator << (YAML::Emitter& out, const employee& v) {
     workday<

写完对应关系之后就是使用
YAML::Emitter emit;
emit< file<

五、随机失败警告

      解析字符有时候能够解析成功,但是有时候又会随机报错,这种情况通常来说是因为重载decode函数的时候,并不是所有路径上都有返回值,导致函数return了一个随机值,这个函数一旦return false,yaml-cpp就会丢出一个异常。

你可能感兴趣的:(yaml)