地区:可能是国家、洲或省活着一种特定的文化。
扩展:1994年通过的ISO C标准修正草案1提供了编写额外国际化程序增加的额外库
- iso646.h
- wctype.h
- wchar.h
25.1 locale.h:本地化
标准库中依赖地区的部分:
- 数值的格式:例如,一些地区小数点是一个圆点(297.48),而在另一些地方则是逗号(297,48)
货币的格式:例如,不同国家的货币符号不同
字符集:例如,亚洲国家通常比西方国家需要更大的字符集
日期和时间的表示形式:例如,一些地方习惯在写日期时先写月(8/24/97),而另一些地方习惯先写日(24/8/97)
25.1.1 类别
说明:
locale.h提供了一系列的以LC_开头的宏来,这些宏分别对某些库的某些方面的行为产生影响。
扩展:C语言的实现提供了其它类型并且定义了上面未列出的以LC_开头的宏。
| 宏 | 影响 | 头文件 | 相关章节 | 备注 | 
|---|---|---|---|---|
| LC_COLLATE | strcoll函数 | string.h | 23.5 | 字符串比较函数 | 
| strxfrm函数 | string.h | 23.5 | 字符串比较函数 | |
| LC_CTYPES | isdigit函数 | ctype.h | 23.4 | |
| isxdigit函数 | ctype.h | 23.4 | ||
| 多字节函数 | stdlib.h | 25.2.1 | ||
| LC_MONETARY | localeconv函数 | locale.h | 影响该函数返回的货币格式信息 | |
| LC_NUMERIC | 格式化输入输出函数中使用的小数点字符 | stdio.h | 22 | 比如 printf和scanf | 
| 字符串转换函数 | stdlib.h | 26.2.1 | atof和strtod | |
| localeconv函数 | locale.h | 该函数返回的非货币格式信息 | ||
| LC_TIME | strftime函数 | time.h | 26.3.2 | 该函数用于将时间转换为字符串 | 
25.1.2 setlocale函数
描述:用来修改当前的地区,也可以用来获取当前地区的信息。
参数:
1: 可以针对一种类型,也可以针对所有类型
| 参数1取值 | 说明 | 
|---|---|
| LC_COLLATE、LC_CTYPE、LC_MONETARY 、LC_NUMERIC、LC_TIME | 针对一种类型 | 
| LC_ALL | 针对所有类型 | 
2: C语言标准为第二个参数仅定义了两种可能值:”c”或” “。其他地区可以针对不同的实现定义。
| 参数二取值 | 说明 | 备注 | 
|---|---|---|
| "C" | 按正常方式执行,小数点是一个句点 | |
| " " | 换到 本地模式(native locale) | C语言标准没有定义切换到本地模式的具体影响 | 
| "Germany" | 德国 | 部分编译器支持 | 
| 类似 en_GB.WIN1252格式的字符串 | 英语_英国.Windows多语言字符集 | 一些常用编译器支持 | 
| NULL | 不设置任何东西 | 仅仅返回指向与当前地区类型的设置相关联的字符串 | 
技巧:如果需要获得与当前地区关联字符串,可以在调用setlocale函数时第一个参数给
LC_ALL,第二个参数给NULL.
原型:locale.h
| 1 | /** | 
| 1 | // 任意程序执行开始时,都会隐含执行调用 | 
| 1 | /* 获取地区信息字符串 */ | 
25.1.3 localeconv函数
描述:获取当前地区的各种信息
原型:locale.h
| 1 | /** | 
struct lconv
说明:存储当前地区的各种信息的结构体
结构成员:有char *和char两种类型
| char *型成员 | 
|---|
|  | 
| char型成员 | 
|---|
|  | 
p_sign_posn和n_sign_posn的值:
案例:用于美国和意大利两国的lconv结构成员的货币型常用值

25.2 多字节字符和宽字符
字符集(美国):
| 分类 | 地位 | 
|---|---|
| ASCII | 主流计算机采用 | 
| EBCDIC | 其他计算机 | 
可扩展字符集:C语言允许编译器提供一种可扩展的字符集
| 可扩展字符集编码 | 说明 | 
|---|---|
| 多字节字符(multibyte character) | 一个或多个字节表示一个可扩展的字符 | 
| 宽字符(wide character) | 一种其值表示字符的整数,具有相同的字节数 | 
基本字符:任何可扩展的字符集必须包含C语言要求的
基本字符(即字母、数字、运算符、标点符、空白字符),而且这些字符要求是单字节的。
用途:c语言同时提供了多字节字符和宽字符用于不同的目的
- 多字节字符:多用于输入/输出,因为输入/输出设备经常是面向字节的
- 宽字符:更适用于程序内部,因为没个宽字符占有相同的空间,便于程序内部操作。
技巧:程序可以读入多字节字符,然后转为便于程序内部操作的宽字符格式,谈后再把宽字符转换回用于输出的多字节格式。
25.2.1 多字节字符
空字符(
\0):无论移位状态如何,c标准都要求\0始终用来表示空字符。而且,\0不能是多字节字符的第二个(或之后)字节。
按是否依赖状态分类:mblen函数、mbtowc函数、wctomb函数都可用检测对字节字符是否是依赖状态的。只要其char *型参数给予NULL实参,则返回非零说明依赖状态;返回零说明依赖状态。
| 分类 | 说明 | 例子 | 
|---|---|---|
| 依赖状态编码(state-dependent enciding) | 每个多字节字符序列都以 初始移位状态(initial shift state)开始,序列中稍后遇到的一些多字节字符会改变移位状态,并且会影响后续字节的含义 | 日本的JIS编码 | 
| 不依赖状态编码 | 每个字符要求一个或者两个字节,但是双字节字符的第一个字节可以始终区别与单字节字符 | 日本的Shift-JIS编码 | 
相关宏:两个
| 宏 | 头文件 | 含义 | 备注 | 
|---|---|---|---|
| MB_LEN_MAX | limit.h | 任意支持区域的最大值 | |
| MB_CUR_MAX | stdlib.h | 当前区域的最大值 | 改变地区可能会影响多字节字符的解释 | 
25.2.2 宽字符
说明:采用特殊实现(比如
unsigned short int)支持的所有宽字符都要求相同的字节数。
宽字符类型:wchar_t(stddef.h、stdlib.h)
宽字符常量和宽字符串常量:L字符(串)常量
- 宽字符常量:
L'a'- 宽字符串常量:
L"abc"
Unicode
说明:非常重要的固定长度编码的字符集。
字符宽度:两个字节
25.2.3 多字节字符/宽字符转换函数
mblen函数
说明:检测s是否指向形成由效多字节字符的字节序列
原型:stdlib.h
2
3
4
5
6
* @param {char *} s 多字节字符的字节序列
* @param {size_t} a 最多能将测的字节的数量(通常为MB_CUR_MAX)
* @return {int} 字符中的字节数:是多字节字符序列;0:空字符;-1:不是多字节字符序列
*/
int mblen(const char *s, size_t a);
| 1 | /** | 
mbtowc函数
说明:将多字节字符串转换为宽字符
原型:stdlib.h.h
| 1 | /** | 
wctomb函数
说明:把宽字符转换为多字节字符
原型:stdlib.h
| 1 | /** | 
| 1 | /** | 
25.2.4 多字节字符/宽字符串函数
mbstowcs函数
说明:把多字节字符序列转换为宽字符序列
- 如何进行转换依赖于当前地区的
LC_CTYPES类别- 当达到上限或者遇到(存储在宽字符数组中的)
\0时,函数停止- 假设要转换的字符串以初始迁移状态开始
原型:
stdlib.h
| 1 | /** | 
wcstombs函数
说明:把宽字符序列转换为多字节字符序列
- 如何进行转换依赖于当前地区的
LC_CTYPES类别- 当达到上限或者遇到(自己存入的)
\0时,函数停止- 产生的字符串是以初始迁移状态开始的
原型:
stdlib.h
| 1 | /** | 
25.3 三字符序列
三字符序列(trigraph sequence):简称“三字符”,是一种三个字符的字符码。以
??字符的形式出现。
用途:可以替换ASCII中的一些特殊字符。
兼容性:尽管不是一直需要,但是所有标准C编译器都要求接受三字符序列。
技巧:字符串中的??可能会被编译器作为三字符序列的开始标志,可以通过使用\将第二个?转义(即?\?)来避免。
| 1 | 
 | 
| 1 | ??=include <stdio.h> | 

