Работа с YAML в C++: библиотеки yaml-cpp и rapidyaml

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с YAML в C++: библиотеки yaml-cpp и rapidyaml

YAML (YAML Ain't Markup Language) — это формат сериализации данных, который широко используется для конфигурационных файлов, файлов описания окружения (Docker Compose, Kubernetes), а также для обмена данными между сервисами. В отличие от JSON, YAML более читаем для человека благодаря отступам и поддержке комментариев.

В C++ нет встроенной поддержки YAML, но существуют отличные сторонние библиотеки. В этой статье мы рассмотрим две самые популярные: yaml-cpp (классическая, простая) и rapidyaml (современная, очень быстрая). Вы узнаете, как установить библиотеки, прочитать YAML-файл, создать его программно и обработать типичные ошибки.

1. Библиотека yaml-cpp

yaml-cpp — это де-факто стандартная библиотека для работы с YAML в C++. Она предоставляет удобный API, напоминающий работу с STL-контейнерами. Библиотека поддерживает спецификацию YAML 1.2.

Установка

Самый простой способ — использовать менеджер пакетов vcpkg или Conan. Для Linux/macOS:

# Установка через vcpkg
vcpkg install yaml-cpp

# Установка через Conan
conan install yaml-cpp/0.7.0@

Если вы предпочитаете собирать вручную, скачайте исходники с GitHub и выполните:

mkdir build && cd build
cmake ..
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: 10

Пример чтения и доступа к данным на C++:

#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") << ")\n";

        // Проверка существования ключа
        if (config["database"]["pool_size"]) {
            int pool = config["database"]["pool_size"].as<int>();
            std::cout << "Pool size: " << pool << "\n";
        }

        // Итерация по последовательности (списку)
        // Предположим, в YAML есть поле: hosts: ["alpha", "beta", "gamma"]
        // for (const auto& h : config["hosts"]) {
        //     std::cout << "Host: " << h.as<std::string>() << "\n";
        // }

    } catch (const YAML::Exception& e) {
        std::cerr << "YAML parsing error: " << e.what() << "\n";
        return 1;
    } catch (const std::exception& e) {
        std::cerr << "General error: " << e.what() << "\n";
        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";
    out << YAML::EndSeq;
    out << Y                    

Рекомендаций