描述:编写一个提供zh_CN支持的程序。
按照软件开发的惯例,最初的软件只有英文版本,根据需要,作者再把软件界面和文档翻译成不同国家、地区的语言版本。但是由于实现翻译的途径、翻译的工作效率、翻译的可重用性等因素各不相同,使翻译工作面临很大困境,也阻碍了软件的推广和应用。为了方便地将软件翻译成不同语言的版本,就需要一套翻译规范和通用工具,这就导致了“国际化”机制的出现。仅仅翻译是不够的,同一种语言在不同国家、地区可能存在多个支系,它们在表达习惯、语法结构甚至文字种类和编码上都有不同,方言更是千奇百怪,通用的翻译其质量肯定是不高的。涉及到计算机领域,还存在操作习惯上的差别,而且对某种语言提供完美的输入、显示、打印、保存、传输并非一件轻而易举的事,这就导致了“本地化”机制的出现。简而言之,“国际化”是“本地化”的一部分,主要是指国际化的实现机制和翻译工作, “本地化”包含“国际化”,是对“国际化”的补充和完善,它还包括为实现对某种特定语言良好的支持而进行的有针对性的翻译调整以及对软件进行的打补丁工作。
I18N 和 L10N 的国际组织是 Openi18n 组织,其前身是 li18nux 组织。它原来是制定 GNU/Linux 自由操作系统上软件全球化标准的国际计划,后来扩充到 GNU/Linux 之外所有开放源代码的技术领域,因而更名为 Open Internationalization Initiative,由非营利组织 Free Standards Group 赞助,并为世界各大厂商所支持,对于 GNU/Linux 系统上的多国语言文字处理技术和环境有决定性的影响。各个开源软件开发组织通常都有负责“国际化”和“本地化”工作的分支机构。
I18N 主要使用 gettext 软件包使软件实现国际化支持。事实上它是一整套 I18N 解决方案。
i18n是internationalization的缩写,意思指i和n之间有18个字母。/etc/sysconfig/i18n里面存放着系统的区域语言设置,可以使linux系统支持国际化信息显示。就是支持多种字符集的转换,避免出现乱码。同一时间i18n只能是英文和一种选定的语言,例如英文+中文、英文+德文、英文+韩文等等。
使用locale查看系统当前locale环境变量
查看/etc/sysconfig/i18n配置(这个是修改后的配置)
按照上面的配置修改/etc/sysconfig/i18n文件,就可以支持中文显示了。
i18n的初始配置如下:
第一行表示当前系统的语言环境变量设置,这里是zh_CN.UTF-8
第二行表示系统支持哪些字符集,没有设置的语言字符集类型会出现乱码
第三行表示系统终端字符的字体,设置的是latarcyrheb-sun16
The/etc/sysconfig/i18n
file sets the default language, any supported languages, and the default system font.
这两个函数都是linux实现i18n需要用到的。
其中setlocale用来设定locale,比如LC_ALL,LC_CTYPE等,一般用法是:setlocale(LC_ALL, "")
这用来设置LC_ALL,第二个参数是一个空字符串表示使用环境变量中定义的LC_ALL的值。
然后就是用bindtextdomain,比如:bindtextdomain("libgammu", LOCALE_PATH);
Linux i18n中,每个资源文件是.mo文件,这个文件是二进制的,用工具针对一个文本生成(作成二进制应该是考虑了性能)。所以,上面的代码 中,LOCALE_PATH指定的就是寻找mo文件的一个路径,一般的,如果调用了上面的代码,那么gettext library就会在这个地方寻找mo文件:
/usr/share/locale-langpack/
此 外,还有textdomain函数,比如:textdomain("gammu"); 这个函数的作用是设置当前需要使用的text domain(这些text domain之前都要使用bindtextdomain来设定好以便能让gettext library找到那个mo文件)。如果我们的程序用到了多个mo文件,那就需要bindtextdomain多次,然后用textdomain来指定当 前需要使用哪个。比如gammu中,gammu命令行程序使用的就是gammu这个text domain,libgammu这个库使用的就是libgammu.mo
附上gammu中使用这两个函数的代码:
#ifdef GETTEXTLIBS_FOUND
void GSM_InitLocales(const char *path) {
/* setlocale, locale is "" means all locale settings are
depend on the environment setting. */
setlocale(LC_ALL, "");
if (path == NULL || strlen(path) == 0) {
#if defined(LOCALE_PATH)
bindtextdomain("libgammu", LOCALE_PATH);
#else
bindtextdomain("libgammu", ".");
#endif
} else {
/* bindtextdomain, libgammu is the catalog, path is the
message file root path. E.g: if path is /usr/share/locale-langpack,
then all messages represented by gettext will by found in:
/usr/share/locale-langpack//LC_MESSAGES/libgammu.mo
Refer to manual of bindtextdomain for more details. */
bindtextdomain("libgammu", path);
}
}
#else
void GSM_InitLocales(const char UNUSED *path) {
setlocale(LC_ALL, "");
}
#endif