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

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

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

Начать курс

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

Интернационализация (сокращённо i18n — от английского "internationalization", где 18 означает количество букв между первой 'i' и последней 'n') — это процесс проектирования программного обеспечения таким образом, чтобы оно могло быть адаптировано к различным языкам и региональным особенностям без изменения кода. В C++ эта задача имеет свою специфику: язык не предоставляет встроенных средств для работы с переводами, но существует несколько мощных библиотек, которые решают эту проблему.

Почему i18n важна для C++ проектов?

Современные C++ приложения редко ограничиваются одним языком. Десктопные программы, игры, серверные решения — все они требуют поддержки нескольких локалей. Основные проблемы, которые решает i18n:

  • Работа с кодировками — переход от ASCII к UTF-8, UTF-16 и другим многобайтовым кодировкам;
  • Форматирование чисел, дат и валют — в разных странах используются разные разделители и форматы;
  • Порядок слов в предложениях — русский язык требует склонений, а английский — артиклей;
  • Плюрализация — правила образования множественного числа различаются (в русском их 3 формы, в английском — 2).

Основные библиотеки для i18n в C++

1. GNU gettext — классика жанра

GNU gettext — самая популярная библиотека для интернационализации в C и C++. Она использует отдельные файлы переводов (.po/.mo) и позволяет изолировать строки от кода.

Базовый пример использования:

#include <iostream>
#include <libintl.h>
#include <locale.h>

#define _(str) gettext(str)

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, которая сканирует исходный код и создаёт .pot файл. Затем переводчики работают с .po файлами.

Преимущества:

  • Простота интеграции;
  • Огромное сообщество и множество инструментов (Poedit, Lokalize);
  • Поддержка плюрализации через ngettext();
  • Работает на любой платформе.

Недостатки:

  • Не поддерживает контекстные переводы без дополнительных ухищрений;
  • Требует отдельного этапа сборки для генерации .mo файлов.

2. Boost.Locale — современный C++ подход

Библиотека Boost.Locale предоставляет более современный и типобезопасный интерфейс. Она построена поверх ICU (International Components for Unicode) или системных локалей.

Пример работы с переводами:

#include <boost/locale.hpp>
#include <iostream>

int main() {
    using namespace boost::locale;
    generator gen;
    std::locale loc = gen("ru_RU.UTF-8");
    std::locale::global(loc);
    
    // Создаём переводчик
    translator tr;
    
    std::cout << tr("Hello, world!") << std::endl;
    std::cout << tr("Today is {1}", "Monday") << std::endl;
    
    // Плюрализация
    std::cout << tr("You have {1} message", "You have {1} messages", 5) << std::endl;
    
    return 0;
}

Преимущества:

  • Нативная поддержка UTF-8;
  • Форматирование дат, чисел и валют;
  • Поддержка контекстных переводов;
  • Работает с std::string и std::wstring.

Недостатки:

  • Зависимость от Boost (тяжеловесная библиотека);
  • Меньше инструментов для переводчиков.

3. ICU — промышленный стандарт

ICU (International Components for Unicode) — это мощная библиотека от IBM, которая предоставляет полный набор инструментов для работы с Unicode и локализацией. Она используется в таких проектах, как Chromium, LibreOffice и Android.

Пример работы с сообщениями:

#include <unicode/msgfmt.h>
#include <unicode/locid.h>
#include <iostream                    

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