對於一個大型的項目而言,肯定會有很多的參數需要改動,如果你把參數放在源代碼裏面,那麼你每次改動都要重新編譯一次程序豈不是很麻煩。所以我們把頻繁改動的參數放在一個文件裏面,想怎麼改就怎麼改動,程序跑起讀取文件就可以獲取參數的數值了,使用過程中配合宏定義和命令行參數解析(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