У меня есть следующий файл gettext .po, который был переведен из файла .pot. Я работаю в системе Linux ( openSUSE , если это важно), использую gettext 0.17.
#
# , 2011
# transer , 2011
msgid ""
msgstr ""
"Project-Id-Version: transtest\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-05-24 22:47+0100\n"
"PO-Revision-Date: 2011-05-30 23:03+0100\n"
"Last-Translator: \n"
"Language-Team: German (Germany)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: transtest.cpp:12
msgid "Min Size"
msgstr "Min Größe"
Теперь, когда я создаю файл .mo через
msgfmt -c transtest_de_DE.po -o transtest.mo
, я проверяю кодировку с помощью «файла» команду,
file --mime transtest_de_DE.po
transtest_de_DE.po: text/x-po; charset=utf-8
, а затем установить ее в мою папку локали и запустить программу после экспорта LANG
и LC_CTYPE
, я получаю мусор, где два не-ASCII символа.
Если я установил кодировку терминала на ISO-8859-2 , а не на UTF-8 , то я вижу два символа правильно.
Заглянув внутрь сгенерированного. mo файл с текстовым редактором, файл, похоже, также находится в UTF-8 (я могу видеть символы, если я установил кодировку своего редактора на UTF-8).
Программа очень проста и выглядит так:
#include
#include
const char *PROGRAM_NAME="transtest";
using namespace std;
int main()
{
setlocale (LC_ALL, "");
bindtextdomain( PROGRAM_NAME, "/usr/share/locale" );
textdomain( PROGRAM_NAME );
cerr << gettext("Min Size") << endl;
}
Я устанавливаю файл .mo в /usr/share/locale/de_DE/LC_MESSAGES/transstest.mo
, и у меня есть экспортировал LC_CTYPE
и LANG
как «de_DE».
$ echo $LC_CTYPE; echo $LANG
de_DE
de_DE
Где я ошибаюсь? Почему gettext дает мне неправильную кодировку (ISO-8859-2) для моих строк, а не запрошенный (в файле .po) UTF-8?
Решение было в вопросе о переполнении стека Не удается заставить (UTF-8) традиционный китайский символ работать с расширением gettext PHP (файлы .po и .mo, созданные в poEdit) , и, похоже, мне нужно было явно вызвать
bind_textdomain_codeset(PROGRAM_NAME, "utf-8");
Окончательный вид программы вот так:
#include
#include
const char *PROGRAM_NAME="transtest";
using namespace std;
int main()
{
setlocale (LC_ALL, "");
bindtextdomain( PROGRAM_NAME, "/usr/share/locale" );
bind_textdomain_codeset(PROGRAM_NAME, "utf-8");
textdomain( PROGRAM_NAME );
cerr << gettext("Min Size") << endl;
}
Никаких изменений ни в одном из моих файлов gettext не требовалось.