我有以下gettext .po文件,该文件已从.pot文件翻译过来。我正在研究Linux系统(openSUSE,如果重要的话),运行gettext 0.17。
#
# <translate@transme.de>, 2011
# transer <translate@transme.de>, 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”命令检查编码,
file --mime transtest_de_DE.po
transtest_de_DE.po: text/x-po; charset=utf-8
然后将其安装到我的locale文件夹并在导出LANG
和LC_CTYPE
后运行程序,我最终得到两个非ASCII字符所在的垃圾。
如果我将终端编码设置为ISO-8859-2,而不是UTF-8,那么我会正确看到这两个字符。
使用文本编辑器查看生成的.mo文件,文件似乎也是UTF-8(如果我将编辑器编码设置为UTF-8,我可以看到符号)。
程序很简单,看起来像这样:
#include <iostream>
#include <locale>
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?
解决方案是在Stack Overflow问题 Can't make (UTF-8) traditional Chinese character to work in PHP gettext extension (.po and .mo files created in poEdit) 中,看来我需要明确调用
bind_textdomain_codeset(PROGRAM_NAME, "utf-8");
最终的计划如下:
#include <iostream>
#include <locale>
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文件。
答案 0 :(得分:4)
如果你有LC_CTYPE=de_DE
(或LANG
),程序假设输出ISO-8859-1(注意,1,而不是2),所以如果你有那个和你的终端设置为utf-8,这是完全错误的。 utf-8的正确语言环境是de_DE.utf-8
。
在您的情况下使用bind_textdomain_codeset
是错误的。如果您想在内部使用固定编码,则使用bind_textdomain_codeset
,例如GNOME可以,但是输出应该总是在locale指定的内容中(通过调用nl_langinfo(CODESET)
获得,这也是gettext默认执行的操作)。