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

相关推荐
Wx120不知道取啥名16 分钟前
C语言之长整型有符号数与短整型有符号数转换
c语言·开发语言·单片机·mcu·算法·1024程序员节
Iareges1 小时前
美团2025校招 广告算法工程师 面经
算法·面试·求职招聘·笔试·秋招
堇舟2 小时前
斯皮尔曼相关(Spearman correlation)系数
人工智能·算法·机器学习
西几3 小时前
代码训练营 day48|LeetCode 300,LeetCode 674,LeetCode 718
c++·算法·leetcode
liuyang-neu3 小时前
力扣第420周赛 中等 3324. 出现在屏幕上的字符串序列
java·算法·leetcode
想做白天梦4 小时前
双向链表(数据结构与算法)
java·前端·算法
小卡皮巴拉4 小时前
【力扣刷题实战】相同的树
c语言·算法·leetcode·二叉树·递归
zyhomepage4 小时前
科技的成就(六十四)
开发语言·人工智能·科技·算法·内容运营
想做白天梦4 小时前
多级反馈队列
java·windows·算法
潇雷4 小时前
算法Day12|226-翻转二叉树;101-对称二叉树;104-二叉树最大深度;111-二叉树最小深度
java·算法·leetcode