C++ Yaml文件解析安裝及使用
安裝 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分成多個選項,然後傳遞給鏈接程序。
參考文章
- C/C++ 靜態鏈接庫(.a) 與 動態鏈接庫(.so) http://www.cnblogs.com/52php/p/5681711.html