Интернационализация (i18n) в C++: полное руководство с gettext и ICU

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

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

Начать курс

Интернационализация (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;
}

Создание файлов перевода

Процесс включает три шага:

  1. Извлечение строк: xgettext --keyword=_ main.cpp -o messages.po
  2. Редактирование .po файла — добавление переводов вручную или через Poedit.
  3. Компиляция в .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 << "Дата: " <<                    

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