小白學習大型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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章