<MyRusakov.ru />

Профессия Web-разработчик

Профессия Web-разработчик

Этот комплект за 8 месяцев превратит Вас в Web-разработчика с нуля. Учиться достаточно 1 час в день.

Начнёте Вы с HTML, CSS и вёрстки сайтов. Потом перейдёте к программированию и JavaScript. Затем изучите PHP, MySQL, SQL, Python. Изучите Web-фреймворки Laravel и Django. Создадите 5 своих сайтов для портфолио.

Комплект содержит:

- 540 видеоуроков

- 110 часов видео

- 1205 заданий для закрепления материала из уроков

- 5 финальных тестов

- 7 сертификатов

- 12 Бонусных курсов

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

std::format в C++20: современное форматирование строк с примерами и лучшими практиками

std::format в C++20: современное форматирование строк с примерами и лучшими практиками

Если вам надоело возиться с iostream‑манипуляторами и опасными printf, самое время освоить std::format в C++20. Он даёт привычный форматный синтаксис, типобезопасность и производительность. Разберёмся на практических примерах и типичных ошибках, чтобы вы смогли сразу применять std::format в рабочих проектах.

Быстрый старт: как подключить и скомпилировать

Поддержка std::format есть в современных компиляторах (GCC 13+, Clang 16+, MSVC 19.3x+). Минимальный пример:

#include <format>
#include <iostream>

int main() {
    std::string name = "Алиса";
    auto s = std::format("Привет, {}!", name);
    std::cout << s << '\n';
}

Компиляция (GCC/Clang):
g++ -std=c++20 main.cpp -O2 -o app

В MSVC достаточно включить стандарт C++20 в настройках проекта.

Синтаксис std::format: место для каждого аргумента

  • Плейсхолдер {} — вставка значения по порядку аргументов.
  • После двоеточия задаётся спецификатор формата: {<spec>}.
  • Внутри можно указывать выравнивание, ширину, заполнитель, систему счисления, точность и знак.
#include <format>
#include <iostream>

int main() {
    // Выравнивание и ширина
    std::cout << std::format("[{:<8}] [:{:^8}] [:{:>8}]\n", 42, 42, 42);
    // Заполнитель (fill)
    std::cout << std::format("{:*^10}\n", "C++"); // ***C++***

    // Числа: ведущие нули, знак, системы счисления
    std::cout << std::format("{:08d}\n", 123);   // 00000123
    std::cout << std::format("{:+d}\n", 5);      // +5
    std::cout << std::format("{:#x}\n", 255);    // 0xff
    std::cout << std::format("{:#b}\n", 10);     // 0b1010

    // Вещественные числа и точность
    std::cout << std::format("{:.2f}\n", 3.14159);  // 3.14
    std::cout << std::format("{:.3e}\n", 12345.0); // 1.235e+04
}

std::format vs printf и iostream

  • Типобезопасность: несовпадение типов ловится на этапе компиляции, если формат — строковый литерал (используется форматный тип format_string).
  • Удобство: один стиль форматирования вместо десятков манипуляторов iostream.
  • Производительность: сравнима с printf, при этом без опасных UB из‑за неверных спецификаторов.

Форматирование времени (chrono)

В C++20 можно красиво форматировать время. Чаще всего достаточно округлить до секунд и задать шаблон:

#include <format>
#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono;
    auto now = system_clock::now();
    auto s = std::format("{:%Y-%m-%d %H:%M:%S}", floor<seconds>(now));
    std::cout << s << '\n';
}

Шаблоны формата схожи с strftime: %Y — год, %m — месяц, %d — день, %H:%M:%S — время.

Печать без cout: std::print из C++23

Если у вас C++23, можно печатать напрямую:

#include <print>

int main() {
    std::print("Hello, {}!\n", "world");
}

В C++20 это ещё недоступно — пользуйтесь std::format + std::cout.

Собственный тип: пишем форматтер за 2 минуты

std::format умеет форматировать ваши структуры, если вы напишете специализацию std::formatter. Пример для точки:

#include <format>
#include <iostream>

struct Point { int x; int y; };

template<>
struct std::formatter<Point> {
    // Простой форматтер: игнорируем формат-спеки
    constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }

    template<class FormatContext>
    auto format(const Point& p, FormatContext& ctx) const {
        return std::format_to(ctx.out(), "({}, {})", p.x, p.y);
    }
};

int main() {
    Point p{3, 4};
    std::cout << std::format("P = {}\n", p);
}

Так вы можете описывать читаемый вывод для доменных сущностей и логов, не засоряя код ручной сборкой строк.

Типичные ошибки и как их избежать

  • Несовпадение типов и спецификаторов. Со строковым литералом компилятор укажет на ошибку; с динамической строкой будет выброшено исключение std::format_error в рантайме.
  • Забыли подключить заголовок: нужен <format> (и иногда <chrono> для времени).
  • Старая версия компилятора. Обновитесь до GCC 13+/Clang 16+/актуального MSVC или временно используйте {fmt}.

Если компилятор ещё не поддерживает std::format

Можно подключить библиотеку {fmt}, на которой основан стандартный std::format. API практически совпадает, а переход позже займёт минуты:

#include <fmt/core.h>
#include <fmt/chrono.h>

int main() {
    fmt::print("Привет, {}!\n", "мир");
}

Небольшая памятка по спецификаторам

  • Выравнивание: ":<width" (влево), ":^width" (по центру), ":>width" (вправо). Заполнитель указывается перед выравниванием: ":*^10".
  • Числа: d (10‑я), x/X (16‑я), b (2‑я), префикс # добавляет 0x, 0b. Ведущие нули: 08d. Знак: + для положительных тоже.
  • Вещественные: f (фикс), e (экспонента), g (умно выбирает), точность: .N.
  • Строки и char форматируются без танцев с бубном: просто {} или с выравниванием.

Практические советы

  • Выносите форматные строки в константы — проще переиспользовать и тестировать.
  • Для логирования определяйте форматтеры доменных типов — логи станут короче и понятнее.
  • Не смешивайте старые printf с std::format: держите проект в едином стиле форматирования.
  • Проверяйте поддержку на CI разными компиляторами, чтобы не поймать сюрпризы.

Что дальше изучать

Освоив std::format в C++20, вы заметите, как ускоряется разработка: меньше шума в коде и меньше ошибок типов. Если хотите системно подтянуть C++ (включая современные фичи стандарта и практику), рекомендую пройти качественный курс: Прокачать C++ с нуля до уровня Гуру на практическом курсе.

Итоги

std::format в C++20 — удобный, безопасный и мощный инструмент для форматирования строк. Он заменяет связку iostream+манипуляторы и устаревший printf, даёт понятный синтаксис, расширяется под ваши типы и открывает путь к ещё более лаконичному std::print в C++23. Применяйте его в логировании, отчётах, диагностике и пользовательских сообщениях — код станет чище и надёжнее уже сегодня.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.