小白学习大型C++源码项目系列之yaml文件

对于一个大型的项目而言,肯定会有很多的参数需要改动,如果你把参数放在源代码里面,那么你每次改动都要重新编译一次程序岂不是很麻烦。所以我们把频繁改动的参数放在一个文件里面,想怎么改就怎么改动,程序跑起读取文件就可以获取参数的数值了,使用过程中配合宏定义和命令行参数解析(sys.argv、argparse解析、getopt解析),从此再也不用担心程序参数的问题了,更多内容可以参考如下文章:
小白学习大型C++源码项目系列之宏定义
小白学习大型C++源码项目系列之命令行参数解析

在程序员的开发生涯中,读写配置文件必不可少。
配置文件有利于我们灵活配置工程,解决大量重复劳动,也方便调试。
配置文件的格式有很多,最简单的有一行一行的文本,也有像 json、xml、protocol buffer 这样结构化的格式,当然也有 yaml 这种格式。
YAML 是专门用来写配置文件的语言,非常简洁和强大,比 JSON和xml格式要方便很多。

yaml-cpp安装

  git clone https://github.com/jbeder/yaml-cpp.git
    cd yaml-cpp
    mkdir build && cd build
    cmake .. && make -j
    sudo make install

read write yaml

ofstream Output file stream (class )链接

  • OpenCV中的XML / YAML数据读写结构是cv :: FileStorage
    FileStorage fs2(“test.yaml”, FileStorage::READ);
    FileStorage fs(“test.yaml”, FileStorage::WRITE);

  • yaml读文件
    YAML::Node config = YAML::LoadFile("…/config.yaml");

  • std::ifstream读文件
    ifstream Input file stream class (class )链接
    std::ifstream fin(“cameracfg.yaml”); // 读入yaml配置文件。

yaml 文件解析

Node 是 yaml-cpp 中的核心概念,是最重要的数据结构,它用于存储解析后的 yaml 信息。Node一共有以下几种type:
Null 空节点
Sequence 序列,类似于一个Vector,对应YAML格式中的数组
Map 类似标准库中的Map,对应YAML格式中的对象
Scalar 标量,对应YAML格式中的常量
生成 Node 的形式有很多种, loadFile() 是最常见的一种。
Node LoadFile(const std::string& filename)
filename 就是yaml文件的路径。
有了 Node 之后,所有的信息都可以检索到。比如 name.
cout << “name:” << config[“name”].as() << endl;
as()表示将解析的内容转换成 string 类型。
你也可以转换成其它类型。

代码实践

#include "yaml-cpp/yaml.h" //安装yaml-cpp参考google code 主页
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
 
typedef struct TagCameraConfigInfoS {
    int cameraId;
    bool isStitch;
    int stFullSizeW;
}CAMERA_CONFIG_INFO_S;
int main()
{
    std::ifstream fin("cameracfg.yaml"); // 读入yaml配置文件。
    try {
        // load yaml file
        YAML::Node doc = YAML::Load(fin);
        if (!doc["cameras"]) {
            printf("the cameras nodes doesn't exist\n");
            return -1;
        }
        // parse cameras params
        std::string sc = "cameras";
        YAML::Node camerasNode = doc[sc];
        for (unsigned int i = 0; i < camerasNode.size(); i++) {
            const YAML::Node& cNode = camerasNode[i];
            std::cout << cNode << "\n";
            std::cout << "===================" << std::endl; 
 
            CAMERA_CONFIG_INFO_S camS;
            camS.cameraId = (i+1);
            camS.isStitch = cNode["isStitch"].as<bool>();
            if (cNode["fullSizeWidth"]) {
                camS.stFullSizeW = cNode["fullSizeWidth"].as<int>();
            } else {
                printf("some camera loss fullSizeWidth param");
                return -1;
            }
            
        }
        std::cout << "parse end!" << std::endl;
    } catch (const YAML::Exception& e) {
        printf("when parsing camera config yaml file error!\n");
        std::cerr << e.what() << "\n";
        return -1;
    }
  return 0;
}

// CMakeLists.txt
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3 -Wall")
add_definitions(-std=c++11)
INCLUDE(FindPkgConfig)
pkg_check_modules(NEW_YAMLCPP yaml-cpp>=0.5)
if(NEW_YAMLCPP_FOUND)
add_definitions(-DHAVE_NEW_YAMLCPP)
endif(NEW_YAMLCPP_FOUND)

对应的yaml文件

    #Camera Config
    cameras:
      - cameraName: FRONT_1
        cameraType: 1
        isStitch: false
        fullSizeWidth: 2048
     
      - cameraName: FRONT_2
        cameraType: 2
        isStitch: true
        fullSizeWidth: 2048
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章