国际化程序实现步骤:
国际化(Internationalization,简写为I18N)是指软件在设计结构和机制上支持多语言的扩展特性,其功能和代码设计不针对某一特定语言和地域。
一:基本实现步骤
1 编辑源程序
用 vim编辑器编辑源程序。注意:要顺利实现程序国际化,源程序应当包含相应的标准头文件,主函数中要调用相关的函数,如库libintl,函数setlocale(),bindtextdomain(),textdomain()等。
如下程序为简单的示例:
#include<stdio.h>
>#include<locale.h>
>#include<libintl.h>
>#include<stdlib.h>
#define _(String) gettext (String)
int main(int argc,char**argv)
{
setlocale(LC_ALL,"");
bindtextdomain("gettext",".");
textdomain("gettext");
printf("%s\n",_("one world,one dream!"));
return 0;
}
2 编译源程序
用gcc命令对源程序进行编译,生成可执行文件。执行后,可以显示源程序中的输入函数的字符。命令示例:
gcc -o gettext gettext.c
3 创建翻译文件模板pot
用xggetxt命令提取源程序中的翻译信息,创建翻译文件模板pot(Portable Object Template可移植的对象模板)文件。命令示例:
xgettext –keyword=_ gettext.c -o gettext.pot
4 由pot生成可移植对象po文件
每一种语言都有其可移植的对象文件,即po(Portable Object )文件。该文件是由一对对的msgid和msgstr组成的,其中,msgid表示从程序中提取的信息,msgstr表示译文。命令示例:
cp gettext.pot gettext.po
5 编辑po文件中的翻译字符,修改字符的编码
用gedit或vim编辑器编辑po文件,翻译相关信息,并将charset改为UTF-8,否则不可编码。完成后,保存文件。注意:如果要实现多种语言,此时应复制多分po文件,并分别进行翻译。命令示例:
gedit gettext.po或vim gettext.po
6 由po文件生成二进制mo文件
用msgfmt命令将po文件转为二进制mo(MachineObject)文件,供计算机读取执行。命令示例:
msgfmt gettext.po -o gettext.mo
7 将mo文件放在正确的目录结构下
mo文件存放位置是否正确是能否实现程序国际化的关键。一般情形下,应将其放在相应地区的locale下相应的子目录中。通常默认目录结构为/usr/locale/share/local,因此本例中生成的mo应放在该目录下相应的子目录中。但是,由于程序中setlocale()函数设定在当前目录结构下查找翻译信息,因此只需在当前目录(即源程序所在目录)下新建相应的地区目录即可。如本例中,可以创建如下目录结构:
zh_CN/LC_MESSAGES/和en_US/LC_MESSAGES/
建好目录后,分别将两个不同的mo文件放在这两目录下
8 设置环境变量
本示例程序会从当前的环境设定LANG来读取地区信息,因此需要设置LANG,如下。注意:每次只能设置一个地区。
LANG=zh_CN.UTF-8
LANG=en_US.UTF-8
9 执行程序,得到结果
在终端界面运行 ./gettext 即可得到所要显示的结果。
二:国际化程序的升级
调试程序的过程中,对源程序进行相应的修改是不可避免的。如何在源程序修改之后,仍能正确的显示当前新修改的翻译,同时又有效利用原来的翻译信息以提高效率,即如何对国际化程序进行“升级”呢?
采用如下步骤可以解决此问题。
1 修改(增、删)源程序
2 运行xgettext生成新的pot文件
命令示例:
xgettext –keyword=_ gettext.c -o gettext.pot
3 将原程序的po文件更名,以区分新pot文件将生成的po文件
命令示例:
mv gettext.po old_gettext.po
4 运行msgmerge将新、旧pot文件进行比较、合并,生成升级版本的po文件
命令示例:
msgmerge old_gettext.po gettext.pot –output-file gettext.po
或者可以使用poedit的POT导入功能
5 为了记录新旧pot的区别,可以用diff命令记录下,两次pot文件中的异同。
命令示例:
diff -u old_gettext.po gettext.po old_gettext.diff
6 在第4步生成新的po文件生成后,可以删除原来的po文件,以免干扰。
命令示例:
rm -f old_gettext.po
7 将新生成的po文件生成mo文件
命令示例:
msgfmt gettext.po -o gettext.mo
8 将新生成的mo文件放在正确的目录结构下
9 设置环境变量
10 执行程序,得到新的结果
三:注意的一些问题
1 源程序中的setlocale()函数与mo文件的目录结构应相一致,否则不能得到正确的结果。
2 编辑po文件时,注意要将字符调整为可移植的编码UTF-8,才可以得到正确结果。否则会有如下警告:
(gettext.po:警告:字符集“CHARSET”不是可移植的编码名称。将消息转换为用户字符集可能不工作。)
3 设置多个环境变量(地区)时,要拷贝多份po并分别进行编辑,并将各自生成的mo文件放在正确的目录下。
4 修改源程序对其进行国际化升级后,应删除原程序(修改前)的可执行文件,否则不能得到修改后的程序的运行结果
四:对源程序的一些解释
#include<stdio.h>
#include<locale.h> //定义本地化函数。
#include<libintl.h>//包含gettext库,gettext是GUN为解决程序国际化问题专门建立的一套工具和库。
#include<stdlib.h>
#define _(String) gettext (String)
int main(int argc,char**argv)
{
setlocale(LC_ALL,"");//设置本程序的环境变量(即指特定地区locale),第一参数是命令的作用域,可以指日期、货币、数字、文本的显示样式;第二参数是一个文本字符串,标志你希望使用哪个地区。若设置成一个空的字符串,则程序会从LANG环境变量获取地区信息。
bindtextdomain("gettext",".");//告诉gettext最终的生成的翻译文件mo的位置,“.”表示在当前目录下寻找mo文件。
textdomain("gettext");//设定翻译环境,即指定使用gettext的翻译。
printf("%s\n",_("one world,one dream!"));
return 0;
}