YAMLの読み込み
yaml-cppを使う。Fedora 35の場合パッケージがあるのでdnfでインストールできる。
$ sudo dnf install yaml-cpp-devel
文字列のパース
#include <iostream>
#include <yaml-cpp/yaml.h>
void test1(void) {
YAML::Node node = YAML::Load("key: value");
// valueが出力される
std::cout << "key == " << node["key"] << std::endl;
// これは何も出力されない
std::cout << "key2 == " << node["key2"] << std::endl;
// これだと例外発生
try {
std::cout << "key2 == " << node["key2"].as<std::string>() << std::endl;
} catch (const YAML::TypedBadConversion<std::string>& e) {
std::cout << "エラー: " << e.msg << std::endl;
}
// aaaが出力される
std::cout << "key2 == " << node["key2"].as<std::string>("aaa") << std::endl;
return;
}
as<T>()
で指定した型で値を取り出せる。キーが存在しない場合などは例外がスローされる。引数にデフォルト値を指定するとキーがなくても例外がスローされることなくデフォルト値が返却される。
ファイルを指定してパース
下記のようなYAMLファイルをロードする。
# hoge
# コメント
config:
number: 12345
number2: aaa
hoge: true
seq:
- name: test1
key: 値
# コメント
- name: test2
key: 値2
#include <iostream>
#include <yaml-cpp/yaml.h>
void test2(const char *file) {
YAML::Node node = YAML::LoadFile(file);
YAML::Node config = node["config"];
std::cout << "number == " << config["number"].as<int>() << std::endl;
// number2: aaaなので、引数で指定した128が返される
std::cout << "number2 == " << config["number2"].as<int>(128) << std::endl;
// std::stringを指定しているのでaaaが返される
std::cout << "number2 == " << config["number2"].as<std::string>() << std::endl;
std::cout << "hoge == " << config["hoge"].as<bool>() << std::endl;
YAML::Node seq = config["seq"];
if (seq.IsSequence()) {
for (const auto seq_node: seq) {
std::cout << "name == " << seq_node["name"] << ", key == " << seq_node["key"] << std::endl;
YAML::Mark mark = seq_node.Mark();
std::cout << (mark.line + 1) << "行目" << std::endl;
}
}
return;
}
Mark()
関数で何行目かの情報が返される。