转自: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字符集@按照欧洲习惯加以修正
注意不是de_DE@euro.UTF-8,所以完全的locale表达方式是
[语言[_地域][.字符集] [@修正值]
生成的locale放在/usr/lib/locale/目录中,并且每个locale都对应一个文件夹,也就是说创建了de_DE@euro.UTF-8 locale之后,就生成/usr/lib/locale/de_DE@euro.UTF-8/目录,里面是具体的每个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

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

  1. docker log 批量删除报错: find: `/var/lib/docker/containers/': 没有那个文件或目录

    问题描述: 服务器上面docker log太多,打算用之前写的批量清理shell脚本清理掉,但是发现报错. find: `/var/lib/docker/containers/': 没有那个文件或目录 ...

  2. 用chattr命令防止系统中某个关键文件被修改

    用chattr命令防止系统中某个关键文件被修改:# chattr +i /etc/resolv.conf

  3. 【未解决】对于使用Windows的IDEA进行编译的文件,但无法在Linux系统中统计代码行数的疑问

    在我学习使用Windows的IDEA的过程中,将代码文件转移到Linux虚拟机当中,但无法在Linux系统中统计代码行数. 注意:拷贝进虚拟机的文件均能编译运行. 具体过程如下: root@yogil ...

  4. find查找文件命令 - Linux系统中的常用技巧整理

    “find”在Linux系统中是比较常用的文件查找命令,使用方法有很多,可以拥有查找文件.文件目录.文件更新时间.文件大小.文件权限及对比文件时间.下面是整理的“find”常用方法,方便以后需要的时候 ...

  5. 牛客网Java刷题知识点之File对象常用功能:获取文件名称、获取文件路径、获取文件大小、获取文件修改时间、创建与删除、判断、重命名、查看系统根目录、容量获取、获取某个目录下内容、过滤器

    不多说,直接上干货! 获取文件名称.获取文件路径.获取文件大小.获取文件修改时间 FileMethodDemo.java package zhouls.bigdata.DataFeatureSelec ...

  6. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib

    今天在linux里安装mysql,运行时遇到这样的错误 ERROR 2002 (HY000): Can't connect to local MySQL server through socket ' ...

  7. mysql Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

    错误原因:/var/lib/mysql目录中socket文件不存在.连接mysql服务器有两种方式:tcp连接,通过socket文件连接.通过socket文件,启动mysql服务,mysql服务会自动 ...

  8. CentOS6.5 [ERROR] /usr/libexec/mysqld: Can't create/write to file '/var/lib/mysqld/mysqld.pid' (Errcode: 2)

    环境是CentOS6.5,先贴个错误代码: 这个问题解决了大半天,浪费了好多时间,不过也算是值了. 事故起因是因为突然断电,mysql server直接干掉了,也没有备用电源,重启了之后看日志tail ...

  9. cloudera-scm-server启动时出现Caused by: java.io.FileNotFoundException: /var/lib/cloudera-scm-server/.keystore (No such file or directory)问题解决方法(图文详解)

    不多说,直接上干货! 问题详情 查看/var/log/cloudera-scm-server.log的启动日志 问题来源 我在用cloudermanager安装好之后,然后,在对如下. 配置kerbe ...

随机推荐

  1. Spring Cloud简单入门教程

    原文地址:http://www.cnblogs.com/skyblog/p/5127690.html 按照官方的话说:Spring Cloud 为开发者提供了在分布式系统(如配置管理.服务发现.断路器 ...

  2. nginx 404重定向到自定义页面

    在访问时遇到上面这样的404错误页面,我想99%(未经调查,估计数据)的用户会把页面关掉,用户就这样悄悄的流失了.如果此时能有一个漂亮的页面能够引导用户去他想去的地方必然可以留住用户.因此,每一个网站 ...

  3. unity, 烘焙lightmap

    1,建一个名为_scene的场景,放一个球体. 2,将球体的Static属性勾选. 3,将默认光源Directional light的Baking属性改为Baked. 4,打开Window->L ...

  4. Android开发系列之性能优化

    一直想整理一篇关于Android性能优化的博客,正好今天借鉴一些书籍资料,总结一下自己对于这块的一些认识.相信大家都听说过16ms的原则,即每两个画面之间的绘制时间间隔不能超过16ms,否则人眼能够感 ...

  5. formail 发送HTML 邮件通过 SENDMAIL

    cat a.html | formail -I "Content-type:text/html;charset=utf-8" -I "Subject:layer4 con ...

  6. gcc使用备忘

    本文为原创文章,转载请指明该文链接 Options Controling the kind of Output -x language 明确说明输入文件的编码语言,没有该选项的话, gcc 会根据输入 ...

  7. IOS设计模式的六大设计原则之单一职责原则(SRP,Single Responsibility Principle)

    定义 就一个类而言,应该仅有一个引起它变化的原因. 定义解读 这是六大原则中最简单的一种,通俗点说,就是不存在多个原因使得一个类发生变化,也就是一个类只负责一种职责的工作. 优点 类的复杂度降低,一个 ...

  8. redis常用数据类型 HyperLoglog

    1.HyperLoglog简介 HyperLoglog是redis新支持的两种类型中的另外一种(上一种是位图类型Bitmaps).主要适用场景是海量数据的计算.特点是速度快.占用空间小. 同样是用于计 ...

  9. 什么是Web Services?

    什么是Web Services? Web Services 是应用程序组件 Web Services 使用开放协议进行通信 Web Services 是独立的(self-contained)并可自我描 ...

  10. 用于ARM上的FFT与IFFT源代码-C语言

    /********************************************************************************* 程序名称:快速傅里叶变换(FFT) ...