C++ Yaml文件解析安装及使用 yaml-cpp
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