Интернационализация (i18n) в C++: от основ до продвинутых техник
Интернационализация (сокращённо i18n — от «internationalization», где 18 — количество букв между первой и последней) — это процесс проектирования программного обеспечения таким образом, чтобы его можно было легко адаптировать для различных языков и регионов без внесения изменений в исходный код. Для языка C++, который традиционно используется в высокопроизводительных и кроссплатформенных приложениях, правильная реализация i18n критически важна. В этой статье мы рассмотрим основные подходы, библиотеки и практические примеры для локализации C++ приложений.
Основные концепции i18n
Прежде чем переходить к инструментам, важно понять ключевые понятия:
- Локализация (l10n) — адаптация переведённого текста, форматов дат, чисел и валют для конкретного региона.
- Локаль — набор правил (язык, регион, кодировка), определяющий форматирование данных.
- Unicode и UTF-8 — стандарт кодирования символов, обязательный для современной интернационализации.
- Плюрализация — корректное отображение форм множественного числа (например, «1 файл», «2 файла», «10 файлов»).
Библиотека GNU gettext для C++
GNU gettext — это наиболее популярный инструмент для интернационализации в мире Unix/Linux, который отлично работает и с C++. Он предоставляет минималистичный API и мощные утилиты для извлечения и управления переводами.
Установка и настройка
Для использования gettext в C++ проекте необходимо установить пакет libintl и подключить заголовочный файл:
#include <libintl.h>
#include <locale.h>
#define _(STRING) gettext(STRING)
Пример базового использования
#include <iostream>
#include <libintl.h>
#include <locale.h>
int main() {
setlocale(LC_ALL, "");
bindtextdomain("myapp", "./locale");
textdomain("myapp");
std::cout << _("Hello, world!") << std::endl;
std::cout << _("File not found") << std::endl;
return 0;
}
Создание файлов перевода
Процесс включает три шага:
- Извлечение строк:
xgettext --keyword=_ main.cpp -o messages.po - Редактирование .po файла — добавление переводов вручную или через Poedit.
- Компиляция в .mo:
msgfmt messages.po -o locale/ru/LC_MESSAGES/myapp.mo
Поддержка плюрализации
Gettext поддерживает множественные формы через функцию ngettext:
int count = 5;
printf(ngettext("%d file deleted", "%d files deleted", count), count);
Библиотека ICU (International Components for Unicode)
ICU — это мощная библиотека от IBM, предоставляющая полный набор инструментов для интернационализации: поддержка Unicode, сортировка с учётом локали, форматирование чисел, дат, валют, работа с часовыми поясами и многое другое. Для C++ используется C++ API из пакета icu4c.
Установка ICU
На Ubuntu/Debian: sudo apt install libicu-dev
На macOS: brew install icu4c
Форматирование чисел и дат
#include <unicode/numfmt.h>
#include <unicode/datefmt.h>
#include <iostream>
int main() {
// Форматирование числа для локали ru_RU
icu::UnicodeString pattern;
icu::NumberFormat* fmt = icu::NumberFormat::createInstance(
icu::Locale("ru", "RU"), status);
icu::UnicodeString result;
fmt->format(1234567.89, result);
std::string utf8;
result.toUTF8String(utf8);
std::cout << "Число: " << utf8 << std::endl; // 1 234 567,89
delete fmt;
// Форматирование даты
icu::DateFormat* dateFmt = icu::DateFormat::createDateInstance(
icu::DateFormat::kFull, icu::Locale("ru", "RU"));
icu::UnicodeString dateStr;
dateFmt->format(icu::Calendar::getNow(), dateStr);
dateStr.toUTF8String(utf8);
std::cout << "Дата: " <<