yaml-cpp:c++ 開發中利用yaml-cpp讀寫yaml配置文件

在程序員的開發生涯中,讀寫配置文件必不可少。

配置文件有利于我們靈活配置工程,解決大量重復勞動,也方便調試。

配置文件的格式有很多,最簡單的有一行一行的文本,也有像 json、xml、protocol buffer 這樣結構化的格式,當然也有 yaml 這種格式。

今天的博文介紹的是如何在 C++ 開發中利用 yaml-cpp 開源庫讀寫 yaml 配置文件。

如果有 Python 開發經驗的同學,可能知道用 Python 讀取 yaml 是再簡單不過了,但是 C++ 麻煩一點,它需要你自己下載源碼然后編譯生成庫文件。


yaml

官方的使用教程在這里
https://github.com/jbeder/yaml-cpp/wiki/Tutorial

1.yaml-cpp

yaml-cpp 是一個開源庫,地址在 github 上,https://github.com/jbeder/yaml-cpp
yaml-cpp 是通過 CMake 來進行構建和編譯的。

在這里假設讀者都有 CMake 相關的經驗,沒有的同學自行百度。我的博文也寫過比較簡單的幾篇,有興趣的可以去看一看。
如果沒有,可以用這段一鍵腳本源碼編譯

#!/bin/bash
yum remove cmake -y && rm -f /usr/bin/cmake
wget -c https://github.com/Kitware/CMake/releases/download/v3.14.2/cmake-3.14.2.tar.gz
tar xvf cmake-3.14.2.tar.gz 
cd $(pwd)/cmake-3.14.2
./bootstrap
gmake
gmake install
ln -s /usr/local/bin/cmake /usr/bin/
cmake --version

首先下載源碼。
https://github.com/jbeder/yaml-cpp
然后,在源碼目錄創建一個 build 文件夾。

mkdir build

進入到 build 文件夾,然后執行 cmake 命令。

cd build

cmake ..
make

注意的是 cmake 后面是 ..,這代表從 build 上一層目錄查找 CMakeLists.txt ,然后編譯的文件都會存放在 build 文件夾,如果對編譯的效果不滿意,只要刪除 build 文件就好了,其他源碼目錄并不受影響,這是 cmake 編譯時的基本套路。

yaml-cpp 默認構建的就是靜態庫,也就是 unix 類系統下的 .a 文件,如果你想構建動態庫的話,就需要在 cmake 時指定。

cmake ..  -D BUILD_SHARED_LIBS=ON //不建議,動態庫需要每個部署環境都安裝

編譯成功后,會生成庫文件,你只需要將庫文件和頭文件拷貝到你自己的工程當中,就可以使用了。

可以看到cmake后make生成了靜態庫文件


libyaml.a

編譯完成后測試一下

make test
test

完全ok

2.需要處理好頭文件。

你如果不想每次都到 copy 頭文件到不同的工程中,那么你可以將頭文件 copy 到系統默認的頭文件目錄,比如 ubuntu 的地址是 /usr/local/include,將庫文件拷貝到系統默認的 lib 文件就好了,比如 ubuntu 是 /usr/local/lib。
其實不用copy到lib,make install會自動把編譯出來的頭文件保存到/usr/local/lib

make install

我建議每次直接拷貝.a文件到工程項目里。有了頭文件和庫,我們就可以順利寫代碼了。
拷貝include目錄,和build目錄下的libyaml.a文件
新建一個文件夾也叫yaml-cpp,把include拷進來,再在里面新建一個lib文件夾,把libyaml.a拷貝進去
形成如下結構的文件夾,以后新建項目我們就把它拷貝到第三方靜態庫文件夾里

mulu

這里我們寫一個簡單的讀取yaml的cpp程序,把我們的靜態庫目錄拷貝進thirdlib文件夾下
項目結構如下
image.png

config.yaml

custom_db:
    db_domain: 10.0.0.8
    db_username: root
    db_passwd: my_passwd
    db_schema: test

redis:
    redis_domain: 10.0.0.10
    redis_passwd: 123456

hello:
    num_config: [1141studio]
    name_config: [powered, by, 1141studio]

hello.cpp

#include <iostream>
#include <string>
#include <stdio.h>
#include <unistd.h>
#include "yaml-cpp/yaml.h"
#include <vector>
const std::string DB_CONF = "config.yaml";
int main(int argc, char * argv[]) {
    /*----------------------------------- test yaml ----------------------------------------*/
    printf("hello world\n");
    std::cout << "this code is only for test yaml" << std::endl;

    /* Node conf. */
    YAML::Node conf = YAML::LoadFile(DB_CONF);
    
    /*----------------------------------- display db_config ----------------------------------------*/
    std::cout << "Database:"<< std::endl;
    std::cout << "domain:  " << conf["custom_db"]["db_domain"].as<std::string>() << std::endl;
    std::cout << "username:" << conf["custom_db"]["db_username"].as<std::string>() << std::endl;
    std::cout << "passwd:  " << conf["custom_db"]["db_passwd"].as<std::string>() << std::endl;
    std::cout << "schema:  " << conf["custom_db"]["db_schema"].as<std::string>() << std::endl;

    /*----------------------------------- display redis ----------------------------------------*/
    std::cout << "Redis" << std::endl;
    std::cout << "redis_domain: " << conf["redis"]["redis_domain"].as<std::string>() << std::endl;
    std::cout << "redis_passwd: " << conf["redis"]["redis_passwd"].as<std::string>() << std::endl;
    
    /*----------------------------------- display hello ----------------------------------------*/
    std::cout << "HelloServer" << std::endl;
    
    /* vector of name string. */
    std::vector<std::string> name_vec = conf["hello"]["num_config"].as<std::vector<std::string> >();
    if(!name_vec.empty())
      std::cout << name_vec[0] << std::endl;
    return 0;
}

編譯

g++ -std=c++11 -I./thirdlib/yaml-cpp/include test_db.cpp -L./thirdlib/yaml-cpp/lib -lyaml-cpp -o HelloServer

其中 -Idir讓編譯器在dir目錄搜索頭文件include
-Ldir讓編譯器在dir目錄搜索靜態庫
-lname讓編譯器鏈接libname.a的目錄

image.png

可以看到成功的讀取了yaml文件,以后的配置文件就不用寫死在代碼里了

更多api可以參考https://cloud.tencent.com/developer/article/1423468
https://www.cnblogs.com/huodaozhe/p/12026327.html

還有類似的json庫jsoncpp:https://blog.csdn.net/guotianqing/article/details/94378309

googletest:https://blog.csdn.net/guotianqing/article/details/104055221

mysql: https://blog.csdn.net/LV_YONG/article/details/80584415

http://www.lxweimin.com/p/5b80aa05199a

http://www.lxweimin.com/p/efdafe4322b9

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容