Ваш C++ — это не только про игры и драйверы
Когда слышишь «C++», часто представляешь себе тяжелую артиллерию: движки Unreal, операционные системы, высоконагруженные серверы. Но есть и другая, не менее полезная сторона — автоматизация задач на C++. Пока коллеги пишут одноразовые баш-скрипты или мучаются с Python-зависимостями, вы можете собрать компактную, быструю утилиту, которая будет работать годами без единого обновления интерпретатора.
В этой статье я покажу, как превратить C++ в швейцарский нож для автоматизации. Мы разберём реальные примеры: от пакетного переименования файлов до парсинга логов и генерации отчётов. Вы увидите, что автоматизация рутины на C++ — это не сложно, а очень выгодно по скорости и надёжности.
Почему C++, а не Python или Bash?
У каждого языка своё место. Но есть сценарии, где C++ даёт фору:
- Скорость выполнения. Если вы обрабатываете терабайты логов — каждая миллисекунда на счету.
- Отсутствие зависимостей. Один статически скомпилированный бинарник работает на любом Linux/Windows без установки интерпретатора.
- Типобезопасность. Меньше сюрпризов в рантайме — критично для автоматизации, которая запускается по расписанию.
- Доступ к системе. Прямая работа с WinAPI, POSIX, реестром, процессами — без прослоек.
Конечно, для быстрого прототипа Python удобнее. Но когда скрипт становится частью CI/CD или production-инфраструктуры, автоматизация на C++ окупается сторицей.
Инструментарий: что нужно знать
Для наших задач не нужен весь C++20. Достаточно базового набора:
std::filesystem(C++17) — работа с файлами и папкамиstd::regex— парсинг текстаstd::fstream/std::stringstream— чтение/записьstd::chrono— замеры времени и логирование
Компилируем с флагом -std=c++17 (или /std:c++17 для MSVC).
Пример 1: Пакетное переименование файлов
Представьте: у вас есть папка с фотографиями IMG_001.jpg, IMG_002.jpg … Нужно привести их к формату 2025_01_15_001.jpg. Руками — 10 минут тоскливой работы. Скриптом — 0.2 секунды.
Код
#include <iostream>
#include <filesystem>
#include <regex>
#include <string>
namespace fs = std::filesystem;
int main() {
std::string dir_path = "./photos";
std::regex pattern(R"(IMG_(\d+)\.jpg)");
std::string prefix = "2025_01_15_";
for (auto &entry : fs::directory_iterator(dir_path)) {
std::string filename = entry.path().filename().string();
std::smatch match;
if (std::regex_match(filename, match, pattern)) {
std::string new_name = prefix + match[1].str() + ".jpg";
fs::rename(entry.path(), entry.path().parent_path() / new_name);
std::cout << "Renamed: " << filename << " -> " << new_name << "\n";
}
}
return 0;
}
Этот пример показывает, как автоматизация задач на C++ с помощью std::filesystem и регулярных выражений решает повседневную проблему за несколько строк. Вы можете легко адаптировать его под свои шаблоны.
Пример 2: Парсинг логов и подсчёт ошибок
Допустим, сервер пишет логи в формате:
2025-01-15 10:23:45 [ERROR] Database connection failed
2025-01-15 10:23:46 [INFO] Retry #1
2025-01-15 10:23:47 [ERROR] Timeout exceeded
Нам нужно собрать статистику: сколько ошибок каждого типа, и вывести топ-5 самых частых сообщений. Bash-однострочник справится, но если логов гигабайты — C++ будет в разы быстрее.
Код
#include <iostream>
#include <fstream>
#include <map>
#include <regex>
#include <vector>
#include <algorithm>
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <logfile>\n";
return 1;
}
std::ifstream file(argv[1]);
std::string line;
std::map<std::string, int> error_count;
std::regex error_pattern(R"(\[ERROR\]\s+(.+))");
while (std::getline(file, line)) {
std::smatch match;
if (std::regex_search(line, match, error_pattern)) {
error_count[match[1].str()]++;
}
}
// Сортируем по убыванию частоты
std::vector<std::pair<std::string, int>> sorted(error_count.begin(), error_count.end());
std::sort(sorted.begin(), sorted.end(),
[](const auto &a, const auto &b) { return a.second > b.second; });
std::cout << "Top 5 errors:\n";
for (size_t i = 0; i < std::min(size_t(5), sorted.size()); ++i) {
std::cout << sorted[i].first << " : " << sorted[i].second << " times\n";
}
return 0;
}
Этот инструмент — пример автоматизации тестирования C++ в действии. Вы можете встроить его в CI-пайплайн и получать сводку после каждого запуска тестов.
Пример 3: Генератор отчётов в HTML
Иногда нужно не просто собрать данные, а красиво их оформить. Напишем утилиту, которая сканирует папку с исходниками и генерирует HTML-отчёт: сколько строк кода, сколько функций, сколько комментариев.
Код
#include <iostream>
#include <fstream>
#include <filesystem>
#include <regex>
#include <sstream>
namespace fs = std::filesystem;
struct FileStats {
int lines = 0;
int functions = 0;
int comments = 0;
};
FileStats analyze_file(const fs::path &p) {
std::ifstream file(p);
std::string line;
FileStats stats;
std::regex func_pattern(R"(\w+\s+\w+\s*\([^)]*\)\s*\{?)");
std::regex comment_pattern(R"(//.*|/\*[\s\S]*?\*/)");
while (std::get