30分鍾學會Yaml-cpp 0.6.0


目前在中文互聯網上有一些關於yaml-cpp,一個cpp的yaml工具的介紹和例子。不過他們都是基於old API的,這里就介紹一下新的API(yaml-cpp>0.6.0)的使用方法。

你可以在這里找到yaml-cpp的庫,安裝和tutorial在上面都有。本文主要是提供一個快速的中文的上手教學。

yaml-cpp的編譯和安裝

這里介紹yaml-cpp的安裝。由於博主在Ubuntu環境下使用yaml-cpp,因此這里針對Ubuntu環境介紹安裝方法。
1.首先克隆倉庫
git clone https://github.com/jbeder/yaml-cpp.git

注意克隆下來的版本,這里是新版本的教程,因此版本應該大等於0.6.0。

2.編譯並安裝yaml-cpp
進入倉庫目錄
cd yaml-cpp
進行編譯
mkdir build && cd build
cmake .. && make
這里按照github主頁上的教程,可以設置一些不同的開關,但是作者也說:

...On a UNIX-y system, simply omit the option to generate a makefile.

當然,Ubuntu屬於這類情況。

編譯成功之后,可以運行一下test測試代碼:
make test
理論上這里不應該報錯。最后,如果你想要將yaml-cpp加入到全局路徑,你應該:
sudo make install
這樣,你就無需指定yaml-cpp的路徑,yaml-cpp編譯出來的頭文件和lib會被安裝到/usr指定位置。你也可以不執行這個操作,這樣你需要在CMakeList中手動指定頭文件和include路徑。

node的增改查刪

Node是yaml-cpp中最重要的數據結構。Node一共有以下幾種type:

  • Null 空節點
  • Sequence 序列,類似於一個Vector,對應YAML格式中的數組
  • Map 類似標准庫中的Map,對應YAML格式中的對象
  • Scalar 標量,對應YAML格式中的常量

以下直接上代碼,詳細的情況請看注釋。

#include <fstream>
#include <yaml-cpp/yaml.h>
#include <iostream>
#include <assert.h>

int main()
{
    YAML::Node node;  
    assert(node.IsNull());  //初始化的節點是Null類型
    node["key"] = "value";  //當你給它賦值鍵值對,它轉變為Map類型
    //node.force_insert("key", "value");//這個操作和上面等價,但是它不會檢查是否存在"key"鍵,不推薦使用
    if(node["mascot"])
        std::cout << node["mascot"].as<std::string>() << "\n";//單純的查詢操作不會增加一個key,當然上面的if不會執行

    node["number"] = 255;
    assert(node.IsMap());   //node是一個Map
    node["seq"].push_back("first element");
    node["seq"].push_back("second element");//node的seq下是Sequence類型,有兩個參數

    YAML::Node node_2;  
    node_2.push_back("first item");//如果你不給node_2鍵值對,它是一個sequence類型
    node_2.push_back("second_item");
    node_2.push_back("third_item");
    std::vector<int> v = {1,3,5,7,9};//給node_2插入了一個Sequence
    node_2.push_back(v);
    assert(node_2.IsSequence());//當然,node_2仍然是一個Sequence

    assert(node_2[0].as<std::string>() == "first item");
    //對於Sequence類型,你可以使用它的下標來訪問
    //注意這里as<T>是一個模板轉換,node_2[0]的type是NodeType::Scalar
    auto it = node_2.begin();
    for(; it != node_2.end(); it++)
        std::cout << *(it) << std::endl;
    //當然,你也可以用迭代器來訪問
    //他們的類型分別是NodeType::Scalar,NodeType::Scalar,NodeType::Scalar,NodeType::Sequence
    //取值時記得使用as進行模板轉換
    node_2["key"] = "value";
    assert(node_2.IsMap());//一旦node_2接收到鍵值對,它轉變為Map類型
    assert(node_2[0].as<std::string>() == "first item");//此時,Sequence時的下標變為它的key值
    node["node_2"] = node_2;//將node_2作為node的一個子項
    node["pointer_to_first_element"] = node["seq"][0];//你也可以給已有的node設置一個別名,類似於一個指針
    assert(node["pointer_to_first_element"].as<std::string>() == "first element");//你可以通過這個指針訪問那個node

    node.remove(node["seq"][0]);//你可以通過指定一個node來刪除它
    node.remove("pointer_to_first_element");//你也可以通過指定key來刪除它
}

如果你執行std::cout << node << endl;應該會得到以下結果:

key: value
number: 255
seq:
  - first element
  - second element
node_2:
  0: first item
  1: second_item
  2: third_item
  3:
    - 1
    - 3
    - 5
    - 7
    - 9
  key: value

至此,Node的增改查刪操作基本介紹完畢。

yaml文件的保存與讀取

Node可以使用文件流的方式進行讀寫,上面的std::cout已經證明了這一點。你可以這樣保存一個node:

std::ofstream file("test.yaml");
file << node <<std::endl;

這樣,上面打印到cout的內容會被輸出到test.yaml文件。
為了讀取一個node,你可以這么做:

std::ifstream file("test.yaml");
YAML::Node node = YAML::Load(file);//讀取來自test.yaml的node文件
std::cout << node <<std::endl;

YAML::Node node_2 = YAML::LoadFile("test.yaml");//也可以這樣讀取文件
std::cout << node_2["node_2"] <<std::endl;//可以直接用下標訪問
for(auto it = node_2.begin(); it != node_2.end(); it++)
    std::cout << it->first << it->second << std::endl;//也可以用迭代器訪問

CMakeList

編寫完源文件以后,在CMakeList中添加如下內容使得程序能夠編譯:

find_package(yaml-cpp REQUIRED)#找到package
add_executable(yaml-test src/yaml-test.cpp)
target_link_libraries(yaml-test yaml-cpp
)#添加鏈接庫

之后就可以使用cmake編譯程序了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM