1

我想本地化我已经编写的程序。它相当大(几乎 50k 行),理想情况下,我想要一个允许我(程序员)做尽可能少的工作的系统,并且不需要对程序进行重大更改 - 如果可能根本没有。

我查看了 gettext() 并非常喜欢它,但我不清楚它将如何翻译如下字符串:

const char *Colors[] = {
 { "Red" },
 { "Blue" },
 { "Yellow" },
 ....
};

这在我的程序中常见。这里用 gettext("Red") 替换 "Red" 显然是行不通的。

所以我想我会做类似的事情,OutputFunction(gettext(Colors[Id])),但是我怎样才能获得要本地化的字符串列表呢?我怀疑任何程序都足够聪明,能够从本地化列表中静态地获取“红色”、“蓝色”、“黄色”。

由于它基本上是一个服务器,因此无需重新编译即可更改语言(我可以为每种支持的语言编译它而没有任何重大问题或烦恼),我想到了 C++0x 的 constexpr,这将是完美的!它可以在数组/等中工作,我很容易在编译时获得要本地化的字符串列表。太糟糕了,还没有编译器实现它。

将所有字符串更改为 ID 不是一种选择,因为这需要我做大量工作,尤其是为每个新字符串创建一个新 id 会很烦人。这同样适用于将上述所有数组转换为其他数组。

那么,有什么想法吗?:/

4

2 回答 2

2

对于您的具体示例,我可能会尝试以下操作:

// presumably globals
const char *Colors_en[] = {
 { "Red" },
 { "Blue" },
 { "Yellow" },
 ....
};
const char *Colors[] = {0};

// in main()
gettextarray(Colors_en, Colors, sizeof(Colors_en) / sizeof(char*));

gettextarray 在每个输入上调用 gettext 并写入一个输出。我认为它可以作为对 std::transform 的调用来实现。您可以通过一些模板技巧来避免 size 参数。

另一种选择是在将要使用任何颜色字符串(显示或附加到字符串以进行显示)的位置调用 gettext。这意味着更改更多代码,但不需要 main() 在执行任何可能使用它们的操作之前翻译程序中的每组字符串。

如果您不想在 main 中进行工作,您可以在使用字符串的代码中进行,如下所示:

if (Colors[0] == 0)
  gettextarray(Colors_en, Colors, sizeof(Colors_en) / sizeof(char*));

或者,如果您的应用程序是多线程的,请考虑pthread_once或使用您使用的线程 API 中的等效项。

于 2009-09-14T01:56:13.307 回答
1

在玩了很多 gettext() 和 xgettext 之后,我想我自己找到了一种方法(对不起,我不喜欢你的方法。必须有数百个这样的数组,我必须将它们全部导入main(),这是很多外部和很多额外的工作:/)。

无论如何,这就是我认为理论上可以做到的方式(我还没有尝试过实际翻译,但我不明白为什么它不起作用)

两个#define:

#define _ gettext
#define __(x) x

然后你使用 _ 来实际翻译,使用 __ 来简单地将字符串标记为“待翻译”:

const char *Colors[] = {
 { __("Red") },
 { __("Blue") },
 { __("Yellow") },
 ....
};

void PrintColor(int id) {
    cout << _("The color is: ") << _(Colors[id]);
}

然后你运行:

xgettext -k_ -k__ *.cpp

你会得到以下 .po 文件:

#: test.cpp:2
msgid "Red"
msgstr ""

#: test.cpp:3
msgid "Blue"
msgstr ""

#: test.cpp:4
msgid "Yellow"
msgstr ""

#: test.cpp:9
msgid "The color is: "
msgstr ""

因此,您使用 __(或任何其他名称,并不重要)作为“虚拟函数”来让xgettext知道需要翻译字符串,并使用 _ 来实际调用 gettext()。

如果你用一个字符串调用_,那么这个字符串也将被标记为要翻译,如果你用一个变量、数组调用它,那么它似乎被xgettext简单地忽略了。

伟大的!现在我所要做的就是浏览 5 万亿个文件并在周围添加下划线,就好像我是一只猴子:/

于 2009-09-14T03:06:00.303 回答