在C++中使用YAML:yaml-cpp和rapidyaml库
YAML(YAML Ain't Markup Language)是一种数据序列化格式,广泛用于配置文件、环境描述文件(Docker Compose、Kubernetes)以及服务间的数据交换。与JSON不同,YAML由于使用缩进并支持注释,对人类更易读。
C++本身不内置支持YAML,但存在优秀的第三方库。在本文中,我们将介绍两个最流行的库:yaml-cpp(经典、简单)和rapidyaml(现代、非常快速)。您将学习如何安装这些库、读取YAML文件、以编程方式创建YAML文件以及处理常见错误。
1. yaml-cpp库
yaml-cpp 是C++中处理YAML的事实标准库。它提供了类似于STL容器的便捷API。该库支持YAML 1.2规范。
安装
最简单的方法是使用vcpkg或Conan包管理器。对于Linux/macOS:
# 通过vcpkg安装vcpkg install yaml-cpp
# 通过Conan安装conan install yaml-cpp/0.7.0@如果您更喜欢手动编译,请从GitHub下载源代码并执行:
mkdir build && cd buildcmake ..cmake --build .sudo cmake --install .解析YAML文件
假设我们有一个配置文件 config.yaml:
server: host: "localhost" port: 8080 debug: true
database: driver: "postgresql" connection_string: "host=localhost dbname=test" pool_size: 10C++读取和访问数据的示例:
#include <yaml-cpp/yaml.h>#include <iostream>#include <string>
int main() { try { // 加载文件 YAML::Node config = YAML::LoadFile("config.yaml");
// 访问嵌套节点 std::string host = config["server"]["host"].as<std::string>(); int port = config["server"]["port"].as<int>(); bool debug = config["server"]["debug"].as<bool>();
std::cout << "Server: " << host << ":" << port << " (debug=" << (debug ? "on" : "off") << ")";
// 检查键是否存在 if (config["database"]["pool_size"]) { int pool = config["database"]["pool_size"].as<int>(); std::cout << "Pool size: " << pool << ""; }
// 遍历序列(列表) // 假设YAML中有字段:hosts: ["alpha", "beta", "gamma"] // for (const auto& h : config["hosts"]) { // std::cout << "Host: " << h.as<std::string>() << ""; // }
} catch (const YAML::Exception& e) { std::cerr << "YAML parsing error: " << e.what() << ""; return 1; } catch (const std::exception& e) { std::cerr << "General error: " << e.what() << ""; return 1; } return 0;}创建YAML文档
使用 yaml-cpp 不仅可以读取,还可以生成YAML:
#include <yaml-cpp/yaml.h>#include <fstream>
int main() { YAML::Emitter out; out << YAML::BeginMap; out << YAML::Key << "application"; out << YAML::Value << "MyApp"; out << YAML::Key << "version"; out << YAML::Value << 2.5; out << YAML::Key << "features"; out << YAML::Value << YAML::BeginSeq; out << "logging" << "auth" << "cache"; ou