您当前位置: 首页 »

C/C++

分类目录归档: C/C++

使用 GetText 实现多国语言的基本方法

假定你已经安装了GetText库,首先写一个“Hello,GetText”的C程序

#include <stdio.h>

int main(int argc, char **argv)
{
	printf("Hello,GetText!\n");
	return 0;
}

我知道你肯定知道上面的代码会输出什么。

接下来开始使用gettext库,首先要加上要用到的locale.h和libintl.h两个头文件,#define _()是为了方便使用,如果不嫌打字麻烦并且看着不碍你的眼,那么你可以直接使用gettext()。然后在主函数的开始设置locale(设置为””会使用环境设置,关于setlocale的更多信息可以参见:http://www.cplusplus.com/reference/clibrary/clocale/setlocale.html)并绑定domain,修改以后的程序是下面这个样子:

#include <stdio.h>
#include <locale.h>
#include <libintl.h>

#define _(STRING) gettext(STRING)
#define PACKAGE "HelloGetText"

int main(int argc, char **argv)
{
	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, "locale");
	textdomain(PACKAGE);

	printf(_("Hello,GetText!n"));
	return 0;
}

然后可以编译这个程序了,当然,编译前你需要将libintl.h和对应静态库文件所在的位置加入Search Directories,以便于编译和链接,而且你要把libintl.lib(GTK for Windows中是libintl.dll.a)加到链接文件中去。

编译链接成功后运行结果,不出意外的话应该显示:

Hello,GetText!

接下来肯定是要做国际化/本地化的工作了,首先我们要生成一个pot文件:

xgettext main.c -k_ -oHelloGetText.pot

使用选项-k_表示只搜索_关键字,如果你使用的是-a选项,那么任何没有使用_()包围的字符串也会被输出到pot中,更多选项参见 xgettext –help

然后针对某一语言生成po文件,以中文为例:

msginit -lzh_CN -iHelloGetText.pot

这条命令会生成zh_CN.po文件,用你喜欢的文本编辑器编辑这个文件,要翻译的字符串是msgid下面对应的msgstr,比如:

#: main.c:14
#, c-format
msgid "Hello,GetText!n"
msgstr "你好,GetText!n"

当然,用PoEdit之类工具翻译会更方便,翻译完成之后我们需要将其编译为mo文件

msgfmt zh_CN.po -o zh_CN.mo

然后把mo文件复制到相应的LC_MESSAGE目录中,在复制前该目录需要存在,Unix-like的OS一般在/usr/share/locale/zh_CN/LC_MESSAGES/或者相对目录的locale/zh_CN/LC_MESSAGES/下,命令如下(cp的-f选项覆盖现有文件):

cp -f zh_CN.mo /usr/share/locale/zh_CN/LC_MESSAGES/HelloGetText.mo

Windows中一般将目录设置为程序运行时当前工作目录相对的locale\zh_CN\LC_MESSAGES,命令如下(copy的/y选项不提示覆盖现有文件):

copy /y zh_CN.mo locale\zh_CN\LC_MESSAGES\HelloGetText.mo

(注:这里的locale即bindtextdomain中设置的locale)

也可以在编译时就直接编译到对应目录,为防止目录不存在,先尝试创建目录,命令如下:

mkdir locale\zh_CN\LC_MESSAGES
msgfmt zh_CN.po -o locale\zh_CN\LC_MESSAGES\HelloGetText.mo

然后再运行HelloGetText程序,如果你是中文的系统,便会显示“你好,GetText!”了。