Internacionalização (i18n) em C++: do básico às técnicas avançadas
Internacionalização (abreviada como i18n — do inglês "internationalization", onde 18 significa o número de letras entre o primeiro 'i' e o último 'n') — é o processo de projetar software de forma que ele possa ser adaptado a diferentes idiomas e características regionais sem alterar o código. Em C++, esta tarefa tem suas particularidades: a linguagem não fornece meios embutidos para trabalhar com traduções, mas existem várias bibliotecas poderosas que resolvem este problema.
Por que i18n é importante para projetos C++?
Aplicações C++ modernas raramente se limitam a um único idioma. Programas de desktop, jogos, soluções de servidor — todos exigem suporte a várias localidades. Os principais problemas que i18n resolve:
- Trabalho com codificações — transição de ASCII para UTF-8, UTF-16 e outras codificações multibyte;
- Formatação de números, datas e moedas — diferentes países usam separadores e formatos diferentes;
- Ordem das palavras nas frases — o português requer conjugações, enquanto o inglês usa artigos;
- Pluralização — as regras para formação do plural variam (no português existem 2 formas, no inglês também 2).
Principais bibliotecas para i18n em C++
1. GNU gettext — o clássico do gênero
GNU gettext é a biblioteca mais popular para internacionalização em C e C++. Ela usa arquivos de tradução separados (.po/.mo) e permite isolar as strings do código.
Exemplo básico de uso:
#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;}Para extrair as strings, utiliza-se a ferramenta xgettext, que escaneia o código-fonte e cria um arquivo .pot. Em seguida, os tradutores trabalham com os arquivos .po.
Vantagens:
- Simplicidade de integração;
- Comunidade enorme e muitas ferramentas (Poedit, Lokalize);
- Suporte a pluralização através de
ngettext(); - Funciona em qualquer plataforma.
Desvantagens:
- Não suporta traduções contextuais sem truques adicionais;
- Requer uma etapa de compilação separada para gerar arquivos .mo.
2. Boost.Locale — abordagem moderna em C++
A biblioteca Boost.Locale fornece uma interface mais moderna e type-safe. Ela é construída sobre o ICU (International Components for Unicode) ou localidades do sistema.
Exemplo de trabalho com traduções:
#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); // Criando o tradutor translator tr; std::cout << tr("Hello, world!") << std::endl; std::cout << tr("Today is {1}", "Monday") << std::endl; // Pluralização std::cout << tr("You have {1} message", "You have {1} messages", 5) << std::endl; return 0;}Vantagens:
- Suporte nativo a UTF-8;
- Formatação de datas, números e moedas;
- Suporte a traduções contextuais;
- Funciona com std::string e std::wstring.
Desvantagens:
- Dependência do Boost (biblioteca pesada);
- Menos ferramentas para tradutores.
3. ICU — padrão industrial
ICU (Intern