修改 /var/lib/locales/supported.d/local 文件(使用 locale -a 命令查看系统中所有已配置的 locale)

转自:http://zyxhome.org/wp/cc-prog-lang/c-stdlib-setlocale-usage-note/ 

      http://www.west263.com/info/html/caozuoxitong/FreeBSD/20090513/126191.html

C 和 C++ 的标准库分别有自己的 locale 操作方法,C 标准库的 locale 设定函数是 setlocale(),而 C++ 标准库有 locale 类和流对象的 imbue() 方法。这篇是我自己的 setlocale() 使用总结。

Linux的glibc中的setlocale()

具体参考:man 3 setlocale

头文件与声明如下:

1 #include <locale.h>
2 charsetlocale(int category, const char* locale);

说明

category:为locale分类,表达一种locale的领域方面,通常有下面这些预定义常量:LC_ALL、LC_COLLATE、LC_CTYPE、LC_MESSAGES、LC_MONETARY、LC_NUMERIC、LC_TIME,其中 LC_ALL 表示所有其它locale分类的并集。

locale:为期望设定的locale名称字符串,在Linux/Unix环境下,通常以下面格式表示locale名称:language[_territory][.codeset][@modifier],language 为 ISO 639 中规定的语言代码,territory 为 ISO 3166 中规定的国家/地区代码,codeset 为字符集名称。

在Linux下,可以使用 locale -a 命令查看系统中所有已配置的 locale。用不带选项的 locale 命令查看当前 Shell 中活动的 locale。用 locale -m 命令查看locale系统支持的所有可用的字符集编码。

和locale相关的包叫做:locales,locale系统支持的所有可用locale在文件:/usr/share/i18n/SUPPORTED 中列出。

在Debian下,可用 dpkg-reconfigure locales 命令重新配置 locale,也可以手工修改 /etc/locale.gen 文件,然后运行 locale-gen 命令。

在Ubuntu下,修改 /var/lib/locales/supported.d/local 文件,配置新的 locale,然后运行 locale-gen 命令。

我在我用的fedora14的linux虚拟机中执行locale 返回如下:

[hehongji@localhost ~]$ locale
LANG=zh_CN.utf8
LC_CTYPE="zh_CN.utf8"
LC_NUMERIC="zh_CN.utf8"
LC_TIME="zh_CN.utf8"
LC_COLLATE="zh_CN.utf8"
LC_MONETARY="zh_CN.utf8"
LC_MESSAGES="zh_CN.utf8"
LC_PAPER="zh_CN.utf8"
LC_NAME="zh_CN.utf8"
LC_ADDRESS="zh_CN.utf8"
LC_TELEPHONE="zh_CN.utf8"
LC_MEASUREMENT="zh_CN.utf8"
LC_IDENTIFICATION="zh_CN.utf8"
LC_ALL=

当 locale 为 NULL 时,函数只做取回当前 locale 操作,通过返回值传出,并不改变当前 locale。

当 locale 为 "" 时,根据环境的设置来设定 locale,检测顺序是:环境变量 LC_ALL,每个单独的locale分类LC_*,最后是 LANG 变量。为了使程序可以根据环境来改变活动 locale,一般都在程序的初始化阶段加入下面代码:setlocale(LC_ALL, "")。

当C语言程序初始化时(刚进入到 main() 时),locale 被初始化为默认的 C locale,其采用的字符编码是所有本地 ANSI 字符集编码的公共部分,是用来书写C语言源程序的最小字符集(所以才起locale名叫:C)。

当用 setlocale() 设置活动 locale 时,如果成功,会返回当前活动 locale 的全名称;如果失败,会返回 NULL。

locale 是一组 C 程式语言处理自然语言(文字)的程式介面, 也可以简单的说,locale 就是一组地区性语言的资讯。由国家语言和各地习俗影响所决定的惯例,或代表一个地理区域的定义所组成,这些惯例包含文字、日期、数字、货币格式和排序等等。这代表着 locale 可让程式的输出可以直接反应地方区域性的文化。

C 语言的 locale 定义,分为下列各大类:
LC_ALL 指定所有的 Locale
LC_CTYPE 字元定义 (包含字元分类与转换规则)
LANG 语言显示
LC_MESSAGES 讯息显示
LC_TIME 时间格式
LC_NUMERIC 数字格式
LC_MONETARY 货币格式
LC_COLLATE 字母顺序与特殊字元比较

其中与一般使用者息息相关的,是字元定义 (LC_CTYPE) 与语言显示 (LANG)。LC_CTYPE 直接关系到某些字元或内码在目前的 locale 下是否可列印?要如何转换字码?对应到哪一个字?.... 等等。LANG 则关系到软体的讯息输出是不是符合地域性,例如 :我们需要的是中文。而一个真正完整支援 locale 系统, 是当使用者在 shell prompt 下,直接设好环境变数後,则马上就能切换到那个语言了。当 LC_MESSAGES、LC_TIME、LC_NUMERIC、 LC_MONETARY 等没有设定的时候,会直接取用 LANG 的环境设定值。
设定 Locale 的字元定义为台湾地区的 utf-8 繁体中文码定义, 有了正确的 locale 的定义後,使得任何地区的语文,只要在加入适当的 locale data 之後,C Library 就能正确地处理软体显示讯息, 而我们使用的中文当然也不例外,而目前常用的中文 locale data 就是 zh_TW.utf-8,代表的就是中文语系(zh)台湾地区(TW) 使用utf-8编码系统(utf-8)。

其中与一般使用者息息相关的,是字元定义 (LC_CTYPE) 与语言显示 (LANG)。LC_CTYPE 直接关系到某些字元或内码在目前的 locale 下是否可列印?要如何转换字码?对应到哪一个字?.... 等等。LANG 则关系到软体的讯息输出是不是符合地域性,例如 :我们需要的是中文。而一个真正完整支援 locale 系统, 是当使用者在 shell prompt 下,直接设好环境变数後,则马上就能切换到那个语言了。当 LC_MESSAGES、LC_TIME、LC_NUMERIC、 LC_MONETARY 等没有设定的时候,会直接取用 LANG 的环境设定值。
设定 Locale 的字元定义为台湾地区的 utf-8 繁体中文码定义, 有了正确的 locale 的定义後,使得任何地区的语文,只要在加入适当的 locale data 之後,C Library 就能正确地处理软体显示讯息, 而我们使用的中文当然也不例外,而目前常用的中文 locale data 就是 zh_TW.utf-8,代表的就是中文语系(zh)台湾地区(TW) 使用utf-8编码系统(utf-8)。
 locale 命名规则:语言_地区名.字元编码名称
当一个程式启动时,系统会预设给它一个初始 locale,称为 POSIX 或 C locale。在此 locale 下,程式的表现会与传统的 C 语言中一样, 使用英文做讯息输出,只能处理英文等 ASCII 码等等。如果该程式有支援 I18N,也就是说它有按照 I18N 的标准来写,则它在启动後就会马上呼叫系统函式来改变它的 locale, 如此它就摇身一变,变成可以处理该 locale 所代表的地区语文了。
zh_TW.utf-8 是目前台湾内广泛使用的 locale, zh 是华语(Chinese),1998 年 ISO639 里面以两个英文字母来代表语言编码, 这个缩写据笔者所知没有任何含义,而 TW 代表的就是台湾(Taiwan) 地区的缩写,最後的 utf-8 则是编码方式。
locale 设定档在编译後, 则是储存在 /usr/share/locale/ 目录下, 以 zh_TW.utf-8 locale 为例,该目录中就包含了 LC_COLLATE、LC_CTYPE、 LC_TIME。
而 LC_MESSAGES 则是储存在 /usr/local/share/locale/zh_TW/LC_MESSAGES/ 或是/usr/X11R6/share/locale/zh_TW.utf-8/ 底下。由於 LC_MESSAGES 类别掌管的是程式讯息输出所用的语言,而且不同程式间的讯息都不会一样,因此它不能像其他类别一样,只提供单一一个资料档即可。相反的,在这里所采取的方式是由各应用程式自行提供它们的讯息资料档, 并统一放在各 locale 的 LC_MESSAGES 的目录下。例如 mutt 程式,其讯息的部分除了英文以外,可能还同时提供了繁体中文、简体中文、 日文、法文等翻译,因此,在以上这些语文所代表的 locale 中, 其底下的 LC_MESSAGES 目录中都会有一份属於 mutt 程式的讯息资料档。 换句话说,在 I18N 架构下,程式讯息部分是与程式分离的, 如此才能分别对各 locale 做 ``区域化'' (即翻译成各地区的语言)。 如此,当 mutt 在执行时,系统会根据目前它的 LC_MESSAGES locale 设定去找找看有没有它的讯息资料档存在,有的话就以该语言做讯息输出, 否则的话则以 C locale 的方式 (即英文) 来输出讯息。

zh_CN.GB2312到底是在说什么?
Locale 是软件在运行时的语言环境, 它包括语言(Language), 地域 (Territory) 和字符集(Codeset)。一个locale的书写格式为: 语言[_地域[.字符集]]. 所以说呢,locale总是和一定的字符集相联系的。下面举几个例子:
1、我说中文,身处中华人民共和国,使用国标2312字符集来表达字符。
zh_CN.GB2312=中文_中华人民共和国+国标2312字符集。
2、我说中文,身处中华人民共和国,使用国标18030字符集来表达字符。
zh_CN.GB18030=中文_中华人民共和国+国标18030字符集。
3、我说中文,身处中华人民共和国台湾省,使用国标Big5字符集来表达字符。
zh_TW.BIG5=中文_台湾.大五码字符集
4、我说英文,身处大不列颠,使用ISO-8859-1字符集来表达字符。
en_GB.ISO-8859-1=英文_大不列颠.ISO-8859-1字符集
5、我说德语,身处德国,使用UTF-8字符集,习惯了欧洲风格。
de_DE.UTF-8@euro=德语_德国.UTF-8字符集@按照欧洲习惯加以修正
注意不是[email protected],所以完全的locale表达方式是
[语言[_地域][.字符集] [@修正值]
生成的locale放在/usr/lib/locale/目录中,并且每个locale都对应一个文件夹,也就是说创建了[email protected] locale之后,就生成/usr/lib/locale/[email protected]/目录,里面是具体的每个locale的内容。
什么是字符集?
字符集就是字符,尤其是非英语字符在系统内的编码方式,也就是通常所说的内码,所有的字符集都放在 /usr/share/i18n/charmaps,所有的字符集也都是用Unicode编号索引的。Unicode用统一的编号来索引目前已知的全部的符号而字符集则是这些符号的编码方式,或者说是在网络传输,计算机内部通信的时候,对于不同字符的表达方式,Unicode是一个静态的概念,字符集是一个动态的概念,是每一个字符传递或传输的具体形式。就像Unicode编号U59D0是代表姐姐的“姐”字,但是具体的这个字是用两个字节表示,三个字节,还是四个字节表示,是字符集的问题。例如:UTF-8字符集就是目前流行的对字符的编码方式,UTF-8用一个字节表示常用的拉丁字母,用两个字节表示常用的符号,包括常用的中文字符,用三个表示不常用的字符,用四个字节表示其他的古灵精怪的字符。而GB2312字符集就是用两个字节表示所有的字符。需要提到一点的是Unicode除了用编号索引全部字符以外,本身是用四个字节存储全部字符,这一点在谈到挂载windows分区的时候是非常重要的一个概念。所以说你也可以把Unicode看作是一种字符集(我不知道它和UTF-32的关系,反正UTF-32就是用四个字节表示所有的字符的),但是这样表述符号是非常浪费资源的,因为在计算机世界绝大部分时候用到的是一个字节就可以搞定的26个字母而已。所以才会有UTF-8,UTF-16等等,要不然大同世界多好,省了这许多麻烦.

通常这几个函数一起用,用于编写本地化程序。
setlocale
bindtextdomain
textdomain
gettext

http://blog.sina.com.cn/s/blog_70f157930101jlz2.html

猜你喜欢

转载自www.cnblogs.com/findumars/p/10247531.html