Unix/Linux编程:地区

不同的国家使用不同的语言,显示诸如数字、货币金额、日期和时间之类的信息时,不同国家的习俗不同… 为此,SUSv3引入了locale用户环境中依赖语言和文化习俗的一个子集

理想情况下,意欲在多个地理区位运行的任何程序都应处理locate的概念,以期以用户的语言和格式来显示和输入信息。这也构成了一个相当复杂的课题——国际化(internationalization)。理想情况下,程序只要一次编写,那么不管运行于何处,总会自动以正确方式来执行IO操作,业就是说,完成本地化任务。

定义

地区信息维护于/usr/share/locale(在一些发行版本中为/usr/lib/locale)之下的目录层次结构中。该目录下的每个子目录都包含一特定地区的信息。这些目录的命名约定如下:

language[_territory][.codeset][@modifier]
  • language 是双字母的 ISO 语言代码。
  • erritory 是双字母的 ISO 国家代码。
  • codeset 表示字符编码集。
  • modifier 则提供了一种方法,用以区分多个地区目录下 language、territory 和 codeset均相同的状况。

de_DE.utf-8@euro 是完整地区目录名称的例子之一,代表地区如下:德语,德国,UTF - 8 字符编码,并采用欧元作为货币单位

[]可以省略。通常情况下,命名只包括语言和国家。因此,en_US 是(说英语的)美国的地区目录,而 fr_CH 则是瑞士法语区的地区目录

当程序中指定要使用的地区时,实际上是指定了/usr/share/locale下某个子目录的名称。如果程序中指定地区不与任何子目录名称相匹配,那么C语言函数库将按照如下顺序将各部分从指定地区(local)中剥离,以寻求匹配

  1. codeset
  2. normalized codeset
  3. territory
  4. modifier

标准化字符编码集(normalized codeset)是一个特定版本字符编码集的名称,剔除了所有非字母、非数字的字符,而且将所有字母转换为小写,最终字符串冠以ISO三个字符。标准化的目的,在于排除字符集名称中因大小写和标点符号而发生的变化。

这里是剥离过程的一个例子,假设为一程序指定的地区为 fr_CH.utf- 8,但并不存在以该名称命名的地区目录,那么如果 fr_CH 目录存在,则与之匹配。如果 fr_CH 目录也不存在,那么将采用 fr 地区目录。万一 fr 目录也不存在,那么setLocale()函数将会报错

/user/share/locale/locale.alias 文件定义了为程序设定地区的替代方法。详见locale.aliases(5)手册页

每个地区子目录中包含由一套文件,指定了此地区的约定设置,如下表所示:

文 件 名目 的
LC_CTYPE该文件包含字符分类(参见 isalpha(3)手册页)以及大小写转换规则
LC_COLLATE该文件包含针对一字符集的排序规则
LC_MONETARY该文件包含对币值的格式化规则(见 localeconv(3)和<locale.h>)
LC_NUMERIC该文件包含对币值以外数字的格式化规则(见 localeconv(3)和<locale.h>)
LC_TIME该文件包含对日期和时间的格式化规则
LC_MESSAGES该目录下所含文件,针对肯定和否定(是/否)响应,就格式及数值做了规定

系统中实际定义的地区可能会各有不同。除了必须定义一个名为POSIX的标准地区外,SUSv3没有对此做出任何要求。

locale 命令显示当前地区环境(本 shell 内)的相关信息。命令 locale – a 则将列出系统上定义的整套地区
在这里插入图片描述

为程序设置地区

函数setlocale()即可设置也可查询程序的当前地区:

NAME
       setlocale - 设置当前的区域选项

总览 (SYNOPSIS)
       #include <locale.h>

       char *setlocale(int category, const char * locale);

描述 (DESCRIPTION)
       setlocale() 函数用来设置或者查询程序当前的区域选项.

       如果 locale不是NULL, 程序就会根据参数更改相应的区域选项.  

	  category参数数选择设置或查询地区的哪一部分.

       LC_ALL 代表所有部分.

       LC_COLLATE
              代表正则表达式匹配(和范围表达式[range expressions]以及字符类[classes]有关系)和字符串排序.

       LC_CTYPE
              代表正则表达式匹配, 字符类(character classification)转换, 区分大小写的比较, 以及宽字符函数.

       LC_MESSAGES
              代表可以本地化的消息(自然语言).

       LC_MONETARY
              代表货币格式.

	   LC_NUMERIC
              代表数字格式 (比如 小数点 和 千位分组符).

       LC_TIME
              代表时间和日期格式.

	   如果 locale 是 NULL, 意味着只是查询当前的区域选项而不更改它

	   当main程序开始的时候可移植的"C"区域选项作为默认值被设置. 一个程序可以在初始化之后调用setlocale(LC_ALL, "" ) 函数, 并且
	   从localeconv()调用的返回中获得和区域选项相关的信息, 如果MB_CUR_MAX > 1就用多字节和宽字节函数来处理文本,strcoll(),    
	   wcscoll() 或者 strxfrm(), wcsxfrm() 来比较字符串, 这样就可以使程序有较好的移植性.


返回值 (RETURN VALUE)
       一个成功的 setlocale()调用会返回一个表示当前区域选项的字符串(指针). 这个字符串可能是在静态存储区中分配的. 之后用相应的category和这个字符串作为参数再去调用这个函数会重新把程序区域选项的相应部分恢复. 如果请求不能完成将会返回 NULL .

使用 setLocale()设置地区有两种不同的方法。locale 参数可能是一个字符串,指定系统上已定义的一个地区(例如,/usr /lib /locale 中的子目录的名称),如 de_DE 或 en_US。另外,地区可能被指定为空字符串,这意味着从环境变量取得地区的设置

setLocale(LC_ALL," ")

我们必须这样调用才能使程序使用环境变量中的地区。如果调用被省略,这些环境变量将不会对程序生效。

如果我们仅需要查看地区的设置而不需要改变它,那么我们可以指定 locale 参数为NULL

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值