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文件根据调用的翻译函数,复制到响应的查找目录就可以得到

相关推荐
雨中rain6 分钟前
贪心算法(2)
算法·贪心算法
sjsjs112 小时前
【数据结构-表达式解析】【hard】力扣224. 基本计算器
数据结构·算法·leetcode
C++忠实粉丝2 小时前
计算机网络socket编程(6)_TCP实网络编程现 Command_server
网络·c++·网络协议·tcp/ip·计算机网络·算法
坊钰2 小时前
【Java 数据结构】时间和空间复杂度
java·开发语言·数据结构·学习·算法
武昌库里写JAVA2 小时前
一文读懂Redis6的--bigkeys选项源码以及redis-bigkey-online项目介绍
c语言·开发语言·数据结构·算法·二维数组
禊月初三2 小时前
LeetCode 4.寻找两个中序数组的中位数
c++·算法·leetcode
学习使我飞升2 小时前
spf算法、三类LSA、区间防环路机制/规则、虚连接
服务器·网络·算法·智能路由器
庞传奇3 小时前
【LC】560. 和为 K 的子数组
java·算法·leetcode
SoraLuna3 小时前
「Mac玩转仓颉内测版32」基础篇12 - Cangjie中的变量操作与类型管理
开发语言·算法·macos·cangjie
daiyang123...3 小时前
Java 复习 【知识改变命运】第九章
java·开发语言·算法