ubuntu16+qt5.6.2+yaml-cpp0.5.3
二.前提
http://blog.csdn.net/azhuty/article/details/68485569(yaml文件来源)
https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML(更多细节可以参考他的wiki)
环境都已经弄好了
三.开工
在项目pro中添加yaml的静态库链接
LIBS +=/home/Desktop/yaml-cpp-release-0.5.3/build/libyaml-cpp.a
INCLUDEPATH+= -l/home/Desktop/yaml-cpp-release-0.5.3/include/yaml-cpp -l
yaml文件格式
subscribers:
- name: "Default task"
topic: "input/cmd_default_check"
timeout: 0.5
priority: 1
short_desc: "Default controller"
- name: "Navigation stack"
topic: "input/cmd_serial_navi"
timeout: 1.0
priority: 3
short_desc: "Navigation controller"
publisher: "output/cmd_vel"
然后qmake
头文件
#ifndef YAML_READ_WRITE_H
#define YAML_READ_WRITE_H
#include
#include
class yaml_read_write
{
public:
yaml_read_write();
YAML::Node DataMem;
YAML::Emitter emitter;
bool dump();
bool setFilePath(std::string path);
private:
std::string filename;
// template
// T getValue(T);
};
#endif // YAML_READ_WRITE_H
DataMem:缓存的读取yaml数据
emitter用来写回文件的
filename具体的文件路径
yaml_cpp
#include "yaml_read_write.h"
#include
yaml_read_write::yaml_read_write()
{
}
bool yaml_read_write::dump()
{
if(!filename.empty())
{
std::ofstream fout(filename);
fout << emitter.c_str();
return true;
}
return false;
}
bool yaml_read_write::setFilePath(std::string path)
{
filename=path;
if(!filename.empty())
{
DataMem=YAML::LoadFile(filename);
}
if (DataMem.IsNull())
return false;
return true;
}
读取一个简单的数据
ui->setupUi(this);
yaml_read_write *yaml=new yaml_read_write();
if( yaml->setFilePath("yaml.yml"))
{
YAML::Node Name=yaml->DataMem["subscribers"];
std::string name=Name[0]["name"].as();
ui->lineEdit->setText(QString::fromStdString(name));
}
在这边需要注意你读取的结构一定要合理
DataMem相当于一个多维的数组你不能读取数组中不存在的项目会被异常
throw TypedBadConversion(node.Mark());
实际上name已经是key[subscribers]的value了
对于Map的读写
此时NameNode的内容如下Name是一个Map
对于list的读写
std::vector
与需要上传的结果一致
写入文件部分
对原有数据进行修改
yaml->DataMem["subscribers"][0]["list"][4]=55;
yaml->DataMem["subscribers"][0]["list"][4]=11;
yaml->dump();
这边有一个好玩的地方
对列表进行修改的话,如果下标越界包括像这种yaml->DataMem["subscribers"][0]["list"]["Key"]="say"
会从sequenceturn to map
感觉大大棒棒哒(这一拨骚走位,服气)
改回来尝试另一种越狱
记住list现在长这样
yaml->DataMem["subscribers"][0]["list"][5]=55;
yaml->dump();
yaml->DataMem["subscribers"][0]["list"][5]=55;当超出list下标+1的时候也会自动变成map
追加一个map
yaml->emitter<DataMem;
yaml->emitter<emitter<emitter<emitter<emitter<emitter<dump();
std::vector squares;
squares.push_back(1);
squares.push_back(4);
squares.push_back(9);
squares.push_back(16);
std::map ages;
ages["Daniel"] = 26;
ages["Jesse"] = 24;
yaml->emitter << YAML::BeginSeq;
yaml->emitter << YAML::Flow << squares;
yaml->emitter << ages;
yaml->emitter << YAML::EndSeq;
yaml->dump();
在已有节点下追加内容
如何在subscribes节点下面插入格式一模一样的比较困难,目前只能找到一种替代方法
利用之前使用过的namenode(特别注意,这里面的Node都是浅复制,使用一片MEM对一个copy进行操作的话就会造成其他也改变)
Name[2]["name"]="ll";
Name[2]["ip"]="118";
总结
1.throwTypedBadConversion
2.注意Node是浅复制,对它数据进行操作的时候需要小心,会影响到其他指向相同内存的Node节点,所以慎用新的Node节点来记录同一份DataMem