自学内容网 自学内容网

linux c国际化

一种locale表示一种文化的各种数据的表示或显示方式,一种locale分成多个部分,不同的部分由category表示,每一种category下面定义了很多关键字keyword

locale -a 查看所有支持的locale,

locale 不带参 查看当前locale的各个category

locale -ck LC_TIME 输出LC_TIME这个category下面的所有keyword

改变category的locale,在输出这个category下面的所有keyword,会发现locale不同keyword会有什么变化

LC_TIME=zh_CN.utf8 locale -ck LC_TIME;

LC_TIME=en_US.utf8 locale -ck LC_TIME

改变category的locale,会发现locale不同date命令输出的时间不同了,这就是locale的直观的影响

LC_TIME=zh_CN.utf8 date

LC_TIME=en_US.utf8 date

locale格式 language[_territory][.codeset][@modifier]

language是 ISO 639 语言代码

Chinese    zh
English    en​
Japanese    ja
Korean    ko

 territory是 ISO 3166 国家/地区代码China    CN
Hong Kong    HK
Taiwan     TW
United States of America    US
Japan    JP
Korea    KR

codeset 字符编码 ISO-8859-1 or UTF-8

man 5 locale 查看locale definition file

man 7 locale 查看国际化多语言编程方面的信息支

 

Locale category有哪些

posix定义的

*  LC_CTYPE

*  LC_COLLATE

 *  LC_MESSAGES  影响与语言翻译相关的函数gettext,  ngettext,   rpmatch

 *  LC_MONETARY

 *  LC_NUMERIC

 *  LC_TIME 影响时间输出函数strftime,strptime

非标准

*  LC_ADDRESS 

*  LC_IDENTIFICATION

*  LC_MEASUREMENT

*  LC_NAME

*  LC_PAPER

*  LC_TELEPHONE

LC_ALL 包含以上所有LC_*

编程接口方面

相关头文件#include <locale.h>

setlocale函数设置当前locale

setlocale(LC_ALL,"")初始化LC_MESSAGES根据下面3个环境变量得第一个非空值

LC_ALL, LC_MESSAGES, LANG

linux c编程字符串国际化gettext系得函数

通过查找message目录将指定字符串根据当前locale翻译得到locale相对于得字符串

#include <libintl.h>

char * gettext (const char * msgid);
char * dgettext (const char * domainname, const char * msgid);
char * dcgettext (const char * domainname, const char * msgid,
                         int category);

msgid表示消息目录中的消息,消息目录由.po文件定义,用msgfmt生成.mo并安装到指定目录

xgettext工具

抽取源码中的字符串,生成message目录,然后可以针对每个字符串翻译

xgettext [OPTION] [INPUTFILE]...

[INPUTFILE]... 源码文件

-f, --files-from=FILE 通过FILE指定源码文件列表

-D, --directory=DIRECTORY 通过DIRECTORY指定查找目录

-d, --default-domain=NAME 输出文件为NAME.po,不指定默认为messages.po

-o, --output=FILE 输出文件为FILE,指定 - 输出到标准输出

-p, --output-dir=DIR 指定输出文件所在目录

-j, --join-existing 与存在得输出文件合并,相当于更新

-k, --keyword 不使用默认关键字,查找字符串

-kWORD, --keyword=WORD,用WORD作为额外得关键字

main.c 代码如图

执行命令

xgettext -k_  -o hello.po main.c

生成得hello.pot如图

hello.pot只是一个模板

cp hello.pot hello.po 

然后修改Language: zh_CN

CHARSET为UTF-8 

其它黄色部分改成自己需要得文字

发布应用时

msgfmt -o 特定规则的目录/xxx.mo xxx.po 

把消息目录文件也就是mo文件放到   特定规则的目录

规则是这样的

dirname/locale/category/domainname.mo

dirname由bindtextdomain函数指定,默认值与系统相关,典型值是prefix/share/locale,prefix是包的安装前缀

locale是当前的locale名,对应GNU实现来说一般是没有国家的语言名,ubuntu实现zh_CN 和 zh

category 对与gettext dgettext两个函数来说是LC_MESSAGES,对dcgettext函数来说就是对应参数

domainname gettext由之前调用的textdomain指定,如果未调用textdomain,domainname默认为messages;dgettext 和dcgettext,domainname 传对应参数指定

从ubuntu18.04系统,使用的翻译函数角度

gettext

dirname为系统目录,/usr/share/locale、/usr/share/locale-langpack

locale 由LC_MESSAGES locale指定,它又是由之前调用的setlocale指定,中文环境通常为zh_CN、zh

category 固定LC_MESSAGES

domainname 由之前调用的textdomain指定,如果未调用textdomain,domainname默认为messages,

所以mo查找的顺序是

1、/usr/share/locale/zh_CN/LC_MESSAGES/messages.mo

2、/usr/share/locale/zh/LC_MESSAGES/messages.mo

3、/usr/share/locale-langpack/zh_CN/LC_MESSAGES/messages.mo

4、/usr/share/locale-langpack/zh/LC_MESSAGES/messages.mo

dgettext,指定的路径找不到还会找系统路径

dirname由bindtextdomain函数指定,如果是相对路径,前面还要加上当前工作目录(getcwd获取),

locale 为zh_CN、zh

category 固定LC_MESSAGES串,注意不是LC_MESSAGES的值

domainname dgettext传对应参数指定,参数为NULL,由之前调用的textdomain指定

当dirname为相对路径c/d,工作目录为/a/b,domainname为hello,时mo查找的顺序是

1、/a/b/c/d/zh_CN/LC_MESSAGES/hello.mo

2、/a/b/c/d/zh/LC_MESSAGES/hello.mo

3、/usr/share/locale-langpack/zh_CN/LC_MESSAGES/hello.mo

4、/usr/share/locale-langpack/zh/LC_MESSAGES/hello.mo

dcgettext

基本同上dgettext,除了

1、没有搜索系统路径/usr/share/locale-langpack

2、locale  由dcgettext的参数指定,此参数必须为<locale.h>中的LC_XXX常量

如果指定LC_NAME,那么dgettext查找目录里面的LC_MESSAGES串换成LC_NAME串,mo查找的顺序是

1、/a/b/c/d/zh_CN/LC_NAME/hello.mo

2、/a/b/c/d/zh/LC_NAME/hello.mo

另外对于翻译时存在字符编码转换的需要,LC_CTYPE locale 会用到

mo文件根据调用的翻译函数,复制到响应的查找目录就可以得到


原文地址:https://blog.csdn.net/FRcheng/article/details/143021754

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!