首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++:如何本地化已经编写的程序

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

Stack Overflow用户
提问于 2009-09-14 01:36:01
回答 2查看 1.2K关注 0票数 1

我想把我已经写好的程序本地化..。它相当大(几乎50k行),理想情况下,我想要一个系统,让我(程序员)做尽可能少的工作量,并且不对程序进行重大修改--如果可能的话,什么也不做。

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

代码语言:javascript
运行
复制
const char *Colors[] = {
 { "Red" },
 { "Blue" },
 { "Yellow" },
 ....
};

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

所以我想我应该做一些类似于OutputFunction(gettext(ColorsId))的事情,但是我如何才能得到一个字符串列表来本地化呢?我怀疑任何程序是否聪明到能够在静态的本地化列表中获得“红色”、“蓝色”、“黄色”。

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

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

那么,有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-09-14 03:06:00

在玩了很多次gettext()和xgettext之后,我想我自己找到了一种方法(抱歉,一个接一个,但我不喜欢你的方法。)肯定有数百个这样的数组,我必须在main()中导入所有这些数组,这是大量的外部工作和大量额外的工作:/)。

不管怎样,我认为理论上是可以这样做的(我还没有尝试过真正的翻译,但我不明白为什么它不起作用)

两个#定义:

代码语言:javascript
运行
复制
#define _ gettext
#define __(x) x

然后使用_进行实际翻译,使用__将字符串标记为“待翻译”:

代码语言:javascript
运行
复制
const char *Colors[] = {
 { __("Red") },
 { __("Blue") },
 { __("Yellow") },
 ....
};

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

然后你跑:

代码语言:javascript
运行
复制
xgettext -k_ -k__ *.cpp

然后得到以下.po文件:

代码语言:javascript
运行
复制
#: 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万亿个文件并在周围添加下划线,就像我是猴子一样:/

票数 1
EN

Stack Overflow用户

发布于 2009-09-14 01:56:13

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

代码语言:javascript
运行
复制
// 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中完成工作,可以在使用字符串的代码中这样做,如下所示:

代码语言:javascript
运行
复制
if (Colors[0] == 0)
  gettextarray(Colors_en, Colors, sizeof(Colors_en) / sizeof(char*));

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1419342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档