C ++:如何本地化已编写的程序

时间:2009-09-14 01:36:01

标签: c++ localization gettext

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

我看了很多gettext()并很喜欢它,但我不清楚如何翻译这些字符串:

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

在我的程序中非常常见..用gettext(“Red”)替换“Red”显然不起作用。

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

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

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

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

2 个答案:

答案 0 :(得分: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中的等效项。

答案 1 :(得分:1)

经过大量的gettext()和xgettext游戏之后,我想我找到了一种方法(抱歉一个人,但我不喜欢你的方法..必须有数百个这样的阵列,我必须全部导入他们在main()中,这是很多外部和很多额外的工作:/)。

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

两个#define's:

#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万亿个文件并在周围添加下划线,好像我是一只猴子:/