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

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

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

配置文件的格式有很多,最簡單的有一行一行的文本,也有像 json、xml、protocol buffer 這樣結(jié)構(gòu)化的格式,當(dāng)然也有 yaml 這種格式。

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

如果有 Python 開發(fā)經(jīng)驗(yàn)的同學(xué),可能知道用 Python 讀取 yaml 是再簡單不過了,但是 C++ 麻煩一點(diǎn),它需要你自己下載源碼然后編譯生成庫文件。


yaml

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

1.yaml-cpp

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

在這里假設(shè)讀者都有 CMake 相關(guān)的經(jīng)驗(yàn),沒有的同學(xué)自行百度。我的博文也寫過比較簡單的幾篇,有興趣的可以去看一看。
如果沒有,可以用這段一鍵腳本源碼編譯

#!/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
然后,在源碼目錄創(chuàng)建一個 build 文件夾。

mkdir build

進(jìn)入到 build 文件夾,然后執(zhí)行 cmake 命令。

cd build

cmake ..
make

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

yaml-cpp 默認(rèn)構(gòu)建的就是靜態(tài)庫,也就是 unix 類系統(tǒng)下的 .a 文件,如果你想構(gòu)建動態(tài)庫的話,就需要在 cmake 時指定。

cmake ..  -D BUILD_SHARED_LIBS=ON //不建議,動態(tài)庫需要每個部署環(huán)境都安裝

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

可以看到cmake后make生成了靜態(tài)庫文件


libyaml.a

編譯完成后測試一下

make test
test

完全ok

2.需要處理好頭文件。

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

make install

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

mulu

這里我們寫一個簡單的讀取yaml的cpp程序,把我們的靜態(tài)庫目錄拷貝進(jìn)thirdlib文件夾下
項(xiàng)目結(jié)構(gòu)如下
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目錄搜索靜態(tài)庫
-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.itdecent.cn/p/5b80aa05199a

http://www.itdecent.cn/p/efdafe4322b9

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容