linux编程之国际化和本地化

1 国际化(internationalization, i18n),本地化(localization, l10n)

这里不多说,想具体了解可以上wikipedia。

2 如何把“Hello world!”打印显示为“你好,世界!”?

1)编辑test_helloworld.c
$vim test_helloworld.c
  1 #include <stdio.h>
  2 #include <locale.h>
  3 #include <libintl.h>
  4 
  5 #define PACKAGE_NAME "test_helloworld"
  6 #define PACKAGE_LOCALEDIR "po"
  7 #define _(x) gettext(x)
  8 
  9 int main (int argc, char *argv[])
 10 {
 11         setlocale(LC_ALL, "");
 12 
 13         // Comment: printf "1 Hello world!"
 14         printf(_("1 Hello world!\n"));
 15 
 16         setlocale(LC_MESSAGES, "zh_CN.UTF-8");
 17 
 18         bindtextdomain(PACKAGE_NAME, PACKAGE_LOCALEDIR);
 19         textdomain(PACKAGE_NAME);
 20 
 21         // Comment: printf "2 Hello world!"
 22         printf(_("2 Hello world!\n"));
 23 
 24         return 0;
 25 }
2)从.c源文件中提取需要进行国际化/翻译的字串,生成.po(portable object file)
$ xgettext --add-comments --keyword=_ test_helloworld.c -o test_helloworld.pot --from-code=UTF-8
$ cp test_helloworld.pot test_helloworld.po
3)修改并翻译字串文件.po

用xgettext命令提取出来的.pot文件内容如下:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-01-14 16:42+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#. Comment: printf "1 Hello world!"
#: test_helloworld.c:14
#, c-format
msgid "1 Hello world!\n"
msgstr ""

#. Comment: printf "2 Hello world!"
#: test_helloworld.c:22
#, c-format
msgid "2 Hello world!\n"
msgstr ""
修改和翻译后的.po文件内容如下:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-01-14 16:42+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#. Comment: printf "1 Hello world!"
#: test_helloworld.c:14
#, c-format
msgid "1 Hello world!\n"
msgstr "1 你好,世界!\n"

#. Comment: printf "2 Hello world!"
#: test_helloworld.c:22
#, c-format
msgid "2 Hello world!\n"
msgstr "2 你好,世界!\n"

可以选择用gedit或自己喜欢的编辑工具来修改,推荐使用poedit工具,方便实用。


4)把翻译好的.po文件转化为程序运行时可读取的二进制文件.mo(machine object file)
$ msgfmt test_helloworld.po -o test_helloworld.mo
5)把转化好的.mo文件放置到相应的LOCALEDIR路径下供程序执行时使用
$ mkdir -p po/zh_CN.UTF-8/LC_MESSAGES/
$ cp test_helloworld.mo po/zh_CN.UTF-8/LC_MESSAGES/
6)最后就可以编译并运行
$ gcc -Wall test_helloworld.c -o test_helloworld
$ ./test_helloworld 
1 Hello world!
2 你好,世界!

3 GNU locale 

locale被设计用来设定当前系统区域环境相关的信息来满足不同用户对国际化和本地化的需要,相关环境变量信息如下:

$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES=en_US.UTF-8
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

4 GNU gettext 

gettext被设计用来实现国际化和本地化,通过gettext可以索引到字串的多国语言翻译,从而为国际化和本地化的字串显示提供基础。

5 Self-check

要理解test_helloworld.c里面相关locale和国际化相关API最好的方法就是亲自读一读glibc中的locale和intl相关目录下的src code,如setlocale.c、textdomain.c、bindtextdom.c、gettext.c等。多用man命令查一下这些命令或API,配合google和wikipedia。

这里只是用中文举例,有兴趣的可以尝试加一下其它语言。

(待完善)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值