C++ Yaml檔案解析安裝及使用 yaml-cpp
阿新 • • 發佈:2018-12-11
安裝 yaml-cpp
克隆官方庫
git clone https://github.com/jbeder/yaml-cpp.git
編譯 yaml-cpp
cd yaml-cpp # 進入克隆的資料夾
mkdir build
cd build
cmake ..
make
make install
沒出現報錯的話就完成了編譯
示例程式碼
robot.cpp
#include "yaml-cpp/yaml.h" //安裝yaml-cpp參考google code 主頁
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
// our data types //這個例子好像是取自開源遊戲引擎ogre,隨便說的
struct Vec3 { //位置座標
float x, y, z;
};
struct Power { //招式,魔法
std::string name; //招式名字,如 葵花寶典
int damage; //傷害值
};
struct Monster { //怪獸
std::string name;
Vec3 position;
std::vector <Power> powers;
};
// now the extraction operators for these types //過載 >> 預算符。。。。
void operator >> (const YAML::Node& node, Vec3& v) {
node[0] >> v.x;
node[1] >> v.y;
node[2] >> v.z;
}
void operator >> (const YAML::Node& node, Power& power) {
node["name"] >> power.name;
node["damage"] >> power.damage;
}
void operator >> (const YAML::Node& node, Monster& monster) {
node["name"] >> monster.name;
node["position"] >> monster.position;
const YAML::Node& powers = node["powers"];
for(unsigned i=0;i<powers.size();i++) {
Power power;
powers[i] >> power;
monster.powers.push_back(power);
}
}
int main() //測試程式
{
std::ifstream fin("robot.yaml"); // 讀入yaml配置檔案。
YAML::Parser parser(fin); //yaml 分析輸入的配檔案。出錯丟擲YAML::ParserException
YAML::Node doc;
parser.GetNextDocument(doc); //doc 就是我們的yaml配置檔案
for(unsigned i=0;i<doc.size();i++) {//i的實際值是0,1,2 ;關聯yaml 中三個大的struct:ogre,dragon,wizard
Monster monster;
doc[i] >> monster;
std::cout << monster.name << "\n";
}
return 0;
}
robot.yaml
- name: Ogre
position: [0, 5, 0]
powers:
- name: Club
damage: 10
- name: Fist
damage: 8
- name: Dragon
position: [1, 0, 10]
powers:
- name: Fire Breath
damage: 25
- name: Claws
damage: 15
- name: Wizard
position: [5, -3, 0]
powers:
- name: Acid Rain
damage: 50
- name: Staff
damage: 3
編譯 robot.cpp
需要制定連結庫
g++ robot.cpp /usr/local/lib/libyaml-cpp.a
如果找不到的話可以使用 find 命令查詢相關檔案
find / -name yaml-cpp.a
如果不這樣可能會報錯:
/tmp/ccYcxLtu.o: In function `main':
robot.cpp:(.text+0x24b): undefined reference to `YAML::Parser::Parser(std::istream&)'
robot.cpp:(.text+0x25a): undefined reference to `YAML::Node::Node()'
robot.cpp:(.text+0x273): undefined reference to `YAML::Parser::GetNextDocument(YAML::Node&)'
robot.cpp:(.text+0x30f): undefined reference to `YAML::Node::size() const'
robot.cpp:(.text+0x331): undefined reference to `YAML::Node::~Node()'
robot.cpp:(.text+0x340): undefined reference to `YAML::Parser::~Parser()'
robot.cpp:(.text+0x388): undefined reference to `YAML::Node::~Node()'
robot.cpp:(.text+0x39c): undefined reference to `YAML::Parser::~Parser()'
/tmp/ccYcxLtu.o: In function `YAML::Node const* YAML::Node::FindValueForKey<std::string>(std::string const&) const':
就是一堆找不到庫檔案
執行結果
Ogre
Dragon
Wizard
難點分析與總結
總結一下知識忙點和誤區
什麼是 .a 與 .so 檔案
靜態連結庫(.a) 與動態連結庫(.so)
- 庫有兩種,一種是 靜態連結庫,一種是 動態連結庫,不管是哪一種庫,要使用它們,都要在程式中包含相應的 include 標頭檔案
靜態連結庫
- 靜態連結庫 即在連結階段,將原始檔中用到的庫函式與彙編生成的目標檔案.o合併生成可執行檔案。該可執行檔案可能會比較大。這種連結方式的好處是:方便程式移植,因為可執行程式與庫函式再無關係,放在如何環境當中都可以執行。 缺點是:檔案太大
- 靜態連結的使用, 需要找到檔案的位置和庫檔名
g++ -o test test.cpp -L./addlib -ladd -L是指定載入庫檔案的路徑 -l是指定載入的庫檔案。
動態連結庫
g++(gcc)編譯選項
- -shared :指定生成動態連結庫。
- -static :指定生成靜態連結庫。
- -fPIC :表示編譯為位置獨立的程式碼,用於編譯共享庫。目標檔案需要建立成位置無關碼,念上就是在可執行程式裝載它們的時候,它們可以放在可執行程式的記憶體裡的任何地方。
- -L. :表示要連線的庫所在的目錄。
- -l:指定連結時需要的動態庫。編譯器查詢動態連線庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.a/.so來確定庫的名稱。
- -Wall :生成所有警告資訊。
- -ggdb :此選項將盡可能的生成gdb的可以使用的除錯資訊。
- -g :編譯器在編譯的時候產生除錯資訊。
- -c :只啟用預處理、編譯和彙編,也就是把程式做成目標檔案(.o檔案)。
- -Wl,options :把引數(options)傳遞給連結器ld。如果options中間有逗號,就將options分成多個選項,然後傳遞給連結程式。