【问题标题】:gettext character encodinggettext 字符编码
【发布时间】:2011-09-05 02:16:47
【问题描述】:

我有以下 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 --mime transtest_de_DE.po
transtest_de_DE.po: text/x-po; charset=utf-8

然后将其安装到我的语言环境文件夹并在导出 LANGLC_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_CTYPELANG 导出为“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 文件进行更改。

【问题讨论】:

  • 我在语言环境上非常不稳定,但是如果你想要 UTF-8 字符串,你不应该设置你的 LANG=de_DE.utf8 吗?
  • 我刚刚尝试过,但似乎没有任何区别,即使我更改了 .mo 安装位置。无论如何,我已经在 .po 文件中指定了它,我原以为它会为 gettext 提供它需要的所有信息。
  • 天哪。五小时后,我找到了这篇文章:stackoverflow.com/questions/2264740/…。哦,好吧,问题解决了……抱歉打扰了!
  • @CodeT,如果该帖子确实提供了您解决问题所需的信息,在此处的答案中总结其内容并接受它。 :) 我没有立即看到该答案对您有何用处,因此希望您的答案将来可以对其他人有所帮助。
  • @CodeT:您现在应该能够将您的解决方案下移至答案,以便我们可以将其从未回答列表中删除。谢谢。

标签: c++ gettext


【解决方案1】:

如果你有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 可以,但输出应始终为语言环境指定的内容(通过调用 nl_langinfo(CODESET) 获得,这也是 gettext 默认执行的操作)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 2011-03-02
    相关资源
    最近更新 更多