2009-09-14 69 views
1

我想本地化一个我已经编写的程序。它相当大(几乎有5万行),理想情况下我想要一个系统让我(程序员)做最少量可能的工作,并且没有重大改变 - 如果可能的话,根本没有。C++:如何本地化一个已经编写的程序

我看着gettext的(),喜欢它了很多,但它是我不清楚它如何转化的字符串,如这些:

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

这是非常共同在我的计划。这里更换带有gettext(“红色”)的“红色”显然不起作用。

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

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

将所有字符串更改为ID不是一个选项,因为它需要大量的工作,尤其是为每个新字符串创建一个新的ID会让人讨厌。这同样适用于将所有数组转换为其他数组。

那么,有什么想法? :/

+1

不是说这对你有帮助,但是就像旁边一样,即使'constexpr'可用,我也怀疑它会帮助你。 'constexpr'只有在函数本身可以在编译时进行评估的情况下才能正常工作,所以如果修改过的'gettext'是基于打开和读取本地化文件的,那么无论如何你都无法使它成为'constexpr'(因为打开&读取文件不能在编译时完成)。鉴于大多数这样的系统都是基于这种方式的,我怀疑'constexpr'确实会有帮助。 – GRB 2009-09-14 01:49:27

回答

1

经过很多玩弄gettext()和xgettext后,我想我找到了一种方式我自己(抱歉onebyone,但我不喜欢你的方法..必须有数百这样的数组,我必须导入所有这些在main()中,这是很多extern和大量额外的工作:/)。

不管怎么说,这是我认为这在理论上可以做到(我还没有尝试尚未实际转换,但我不明白为什么它不会工作)

两个#定义的:

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

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的调用来实现。你可以通过一些模板欺骗来避免大小参数。

另一种选择是在任何颜色字符串即将使用(显示或附加到字符串以供显示)时调用gettext。这意味着改变更多的代码,但并不要求main()在执行任何可能使用它们的任何事情之前先转换程序中的每一组字符串。

如果你不想做的主要工作,你能做到这一点在使用字符串中的代码,这样的事情:

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

或者,如果您的应用程序是多线程的,考虑pthread_once或相当于您使用的线程API。

相关问题