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

发表于: C/C++ |

假定你已经安装了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!”了。

The damn “for” in batch file!

发表于: 脚本 |

本来想在单个批处理文件里面实现类似下面的操作:

echo off
SET num=0
FOR /D %%i IN (*) DO (
SET /a num=%num%+1
echo %num%.%%i
)
echo %num%
pause>nul

结果发现这个该死FOR里面居然不能改变%num%的值,查了下 FOR /? 说是要用CMD /v启动命令行,然后把%num%改成!num!,我本来的目的是直接双击这一个批处理就完成操作的,看来不能用批处理实现了,去除这个部分,结果就有些不完美了,转向研究VBS中,看看VBS脚本能不能比较完美地实现我想要完成的功能,没找到好点的脚本对象手册,MSDN网上查又太慢,比较郁闷的

本博第一文

发表于: 杂谈 |

很随意的在这里发表一些文章,基本上是跟技术相关的,文章涉及面也很随意,只要感兴趣的,或者平时解决的一些问题,都有可能发表在这里。

发表文章的时间也很随意的,也就是说有时候可能一天会发个几篇,也可能一年半载也没反应。

访问量也很随意的,一天不到1个IP我也不会介意,小博而已么,不用太在意这些(其实,看得人多我当然会开心啦!)。