locale.h
C语言要用在哪里,都应该包含什么内容,包括什么功能。随着历史中各种需求的沉淀,和各种实现的积累,C标准也日趋于完善。历经了5年的成长,看来一切都基本完成,可以画上一个句号了。剩下的工作只是一些修修补补的小改动。正当X3J11委员会的成员们一致认为他们过去的工作“将已经有的实践制定为标准”很好的成就了C标准的构建,并且C标准已经基本完成。这时候,也正是C用在世界各地比较高峰的时期,一个一直以来未被留意的问题日渐明显了。C语言中处理数字、货币、时间日期格式、字符这些只是美国人的标准,或者说是美国人的习惯。欧洲人怎么办?也遵守美国人的习惯?反对ANSI C标准做为世界标准的声音在欧洲地区响起,他们与其接受美国人的习惯,不如等候真正国际化的实现的到来。在这样的局势下,AT&T Bell实验室专门召开会议来讨论这个问题,就是现在我们称为的 国际化(I18N)。在会议中提出在C中实现区域设置的功能。编写适应性强的程序,比如程序运行在美国的电脑,操作习惯是美国人的,运行在欧洲电脑上,就是欧洲人的,这种问题,其实在更早,大约当时的15年前就已经有有效果的解决方法。就是环境变量。在C语言中要读取到一个环境变量的值,可以用中定义的函数getenv。其实,区域设置本质上也就是这个问题,将货币处理设置相应的环境变量,数字,字符等,都设置上相应的环境变量,按照需要,总共应该有将近二十个环境变量,一一设置好了,问题就得以解决。区域设置是一个比环境变量方法更改进的方案。你只要设置到一个区域,里面整套的几十个环境变量就相应的改变了。不用一一设置,不容易出错。在这个环境下locale诞生了,那么到底什么是locale呢?locale这个单词中文翻译成地区或者地域,其实这个单词包含的意义要宽泛很多。Locale是根据计算机用户所使用的语言,所在国家或者地区,以及当地的文化传统所定义的一个软件运行时的语言环境。这个用户环境可以按照所涉及到的文化传统的各个方面分成几个大类
- 符号及其分类(LC_CTYPE)
- 数字 (LC_NUMERIC)
- 比较和排序习惯(LC_COLLATE)
- 时间显示格式(LC_TIME)
- 货币单位(LC_MONETARY)
- 信息,主要是 提示信息,错误信息, 状态信息, 标题, 标签, 按钮和菜单等(LC_MESSAGES)
- 姓名书写方式(LC_NAME)
- 地址书写方式 (LC_ADDRESS),电话号码书写方式 (LC_TELEPHONE),度量衡表达方式(LC_MEASUREMENT),默认纸张尺寸大小 (LC_PAPER)和locale对自身包含信息的概述(LC_IDENTIFICATION)。
这12个信息根据不同的地区,使用习惯肯定是不一样的,除了这12个LC_*
信息以外,为了方便使用,还有另外两个变量LC_ALL
和LANG
,他们之间的优先级关系是这样的LC_ALL > LC_* > LANG
,这里大家可以参考这篇文章,对locale已经讲得很详细了http://www.cnblogs.com/dolphi/p/3622439.html看完你会对字符集和国际化有个更清晰的认识。
搞清楚了locale的由来,我们来看看locale.h里面都有什么,这个头文件平常我们使用的不多,里面也很简单,真正能用到的就只有一个结构体和两个函数。
结构体如下
struct lconv
{
/* 数字(非币值)信息 */
char *decimal_point; /* 数字的小数点符号 */
char *thousands_sep; /* 数字的千分组分隔符 */
/* 每个元素为相应组中的数字位数,索引越高的元素越靠左边。一个值为CHAR_MAX的 元素表示没有更多的分组了。一个值为0的元素表示前面的元素能用在靠左边的所有分组中 */
char *grouping; /* 数字分组分隔符 */
/* 货币信息 */
char *int_curr_symbol;
char *currency_symbol; /* 本地货币符号 */
char *mon_decimal_point; /* 货币的小数点号 */
char *mon_thousands_sep; /* 倾向的千分组分隔符 */
char *mon_grouping; /* 类似于grouping元素(参考上面) */
char *positive_sign; /* 正币值的符号 */
char *negative_sign; /* 负币值的符号 */
char int_frac_digits; /* 国际币值的小数部分 */
char frac_digits; /* 本地币值的小数部分 */
char p_cs_precedes; /* 如果currency_symbol放在正币值之前则为1,否则为0 */
char p_sep_by_space; /* 当且仅当currency_symbol与正币值之间用空格分开时为1 */
char n_cs_precedes; /* 如果currency_symbol放在负币值之前则为1,否则为0 */
char n_sep_by_space; /* 当且仅当currency_symbol与负币值之间用空格分开时为1 */
/* 正值和负值符号的定位:
0 用圆括号括住数量和currency_symbol
1 正负号放在数量和currency_symbol之前
2 正负号放在数量和currency_symbol之后
3 正负号正好放在currency_symbol之前
4 正负号正好放在currency_symbol之后 */
char p_sign_posn;
char n_sign_posn;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
函数如下
/* 返回指向当前lconv对象的指针,包含本地化信息 */
struct lconv * localeconv(void)
/* 设定本地化信息 */
char * setlocale(int category,const char * locale);
- 1
- 2
- 3
- 4
- 5
其中category参数设定成不同的形式会有不同的影响,具体如下
参数 | 影响 |
---|---|
LC_ALL | 全部本地化信息 |
LC_COLLATE | 影响strcoll和strxfrm |
LC_CTYPE | 影响字符处理函数和多行字符处理函数 |
LC_MONETRAY | 影响localeconv返回的货币格式化信息 |
LC_NUMERIC | 影响格式化输入输出字符中的小数点符号 |
LC_TIME | 影响strftime函数 |
locale有两种,格式如下
参数 | 作用 |
---|---|
“” | 采用当前环境下默认的本地化格式 |
“C” | 采用C本地化方式 |
这里列举个简单的使用案例
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
wchar_t s[] = {25105, 29233, 20320, 0};
setlocale(LC_ALL, "");
printf("%ls\n", s);
return 0;
}
[ghj@localhost ~]$ gcc locale.c -o locale
[ghj@localhost ~]$ ./locale
我爱你
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
这里如果不加setlocale
的话终端是不会有信息输出的。