C标准库源码解剖(3):字符处理函数ctype.h和wctype.h
分类:C 2009-10-05 18:47 525人阅读评论(0) 收藏举报
字符处理包括分类(即属性判断)和转换函数。ASCII字符主要可分类为控制字符、空白字符、可打印字符、数字字符、字母字符(大写和小写)、标点符号等。
1、ctype.h:标准的属性判断函数有
isalnum,isalpha,iscntrl,isdigit,isxdigit,isgraph,isprint,ispunct,islower,isupper,isspace, isblank(C99中引入)共12个函数。标准的属性转换函数有tolower和toupper。当然具体的实现中还会提供一些非标准函数作为扩展,如glibc的实现中提供了
isctype,isascii,toascii。
view plaincopy to clipboardprint?
1. /* ISO C99 Standard 7.4: 字符处理  <ctype.h> */
2. #ifndef _CTYPE_H
3. #define _CTYPE_H    1
4. #include <features.h>  /* 定义了一些表示编译选项的宏 */
5. #include <bits/types.h>
6. __BEGIN_DECLS
7. #ifndef _ISbit
8. /* 下面这些是所有的字符属性,如果超过16种不同的属性,那很多使用
unsigned short int的
9. 的函数代码都要改变。这些属性被存储为网络字节序(大端字节序),我们为
每个属性定义一个
10.    依赖于机器字节序的比特位解释 */
11. # include <endian.h>
12. # if __BYTE_ORDER == __BIG_ENDIAN  /* 如果是大端字节序 */
13. #  define _ISbit(bit)  (1 << (bit))
14. # else /* 否则__BYTE_ORDER==__LITTLE_ENDIAN,是小端字节序 */
15. #  define _ISbit(bit)  ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
16. # endif
17. enum
18. {
19.  _ISupper = _ISbit (0),    /* 大写字母字符A~Z:0x41~0x5A  */
20.  _ISlower = _ISbit (1),    /* 小写字母字符a~z:0x61~0x7A  */
21.  _ISalpha = _ISbit (2),    /* 字母字符A~Za~z  */
22.  _ISdigit = _ISbit (3),    /* 十进制数字字符0~9:0x30~0x39  */
23.  _ISxdigit = _ISbit (4),  /* 十六进制数字字符0~9A~Fa~f  */
24.  _ISspace = _ISbit (5),    /* 空白字符:0x9~0xD,0x20。包括水平制表符/t,换
行符/n,
25.                                        垂直制表符/v,换页符/f,回车符/r,空格符' '  */
26.  _ISprint = _ISbit (6),    /* 可打印字符:0x20~0x7E。即任何非控制字符  */
27.  _ISgraph = _ISbit (7),    /* 图形字符:除空格以外的可打印字符  */
28.  _ISblank = _ISbit (8),    /* 空白分隔符:通常是空格符和水平制表符(Space和
Tab键)  */
29.  _IScntrl = _ISbit (9),    /* 控制字符:0x0~0x1F,0x7F  */
30.  _ISpunct = _ISbit (10),  /* 标点符号  */
31.  _ISalnum = _ISbit (11)    /* 字母和数字字符  */
32. };
33. #endif /* ! _ISbit  */
34. /* 这些函数定义在ctype-info.c中。这里的描述必须与localeinfo.h中的一致。
35.    在依赖于线程的区域模型中(参看<local.h>中的uselocale),我们不能像过
去那样对这些
36.    函数使用全局变量,现在这些访问函数返回每个变量的地址,这是多线程环境
中当前线程的本
37.    地地址。
38.    这些指针指向一个大小为384的数组中,因此它们可以通过以下几种下标值
来访问:任何[0,255]内的
39.    unsigend char值;EOF(-1);任何[-128,-1)内的signed char值。ISO C要求
ctype中
40.    的函数工作在unsigend char或EOF上;这里我们同时也支持负的
signed char值以兼容老的程序。
41.    大小写转换数组是int的,而不是unsigned char,因为tolower(EOF)的结果
必须是EOF,这并不
42.    是一个unsigned char。但是今天更重要的是数组也会在多字节字符集中使
用 */
43. extern __const unsigned short int **__ctype_b_loc (void)
44.      __attribute__ ((__const));
45. extern __const __int32_t **__ctype_tolower_loc (void)
46.      __attribute__ ((__const));
47. extern __const __int32_t **__ctype_toupper_loc (void)
48.      __attribute__ ((__const));
49. #define __isctype(c, type) /
50.  ((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type)
51. #define __isascii(c)    (((c) & ~0x7f) == 0) /* 如果C是一个7比特的值,说明是
一个ascii字符(0~127)  */
52. #define __toascii(c)    ((c) & 0x7f)        /* 屏蔽掉高位  */
53. /* 用宏来声明ctype中的各个函数原型,以简化代码 */
54. #define __exctype(name) extern int name (int) __THROW
55. __BEGIN_NAMESPACE_STD
56. /* 下面的名称是所有的函数:
57.    int isCHARACTERISTIC(int c);
58.    当且仅当C有属性CHARACTERISTIC时返回非0值(真),
59.    对CHARACTERISTIC名称的含义,参看上面的enum
60.    函数形参是一个字符,用int类型描述 */
61. __exctype (isalnum);  /* 这里是各个函数原型声明 */
62. __exctype (isalpha);
63. __exctype (iscntrl);
64. __exctype (isdigit);
65. __exctype (islower);
66. __exctype (isgraph);
67. __exctype (isprint);
68. __exctype (ispunct);
69. __exctype (isspace);
70. __exctype (isupper);
71. __exctype (isxdigit);
72. /* 返回C的小写形式  */
73. extern int tolower (int __c) __THROW;
74. /* 返回C的大写形式  */
75. extern int toupper (int __c) __THROW;
76. __END_NAMESPACE_STD
77.
78. /* ISO C99引入了一个新函数  */
79. #ifdef  __USE_ISOC99
80. __BEGIN_NAMESPACE_C99
81. __exctype (isblank);
82. __END_NAMESPACE_C99
83. #endif
84. #ifdef __USE_GNU
85. /* 根据掩码MASK来测试C是否属于某个字符集  */
86. extern int isctype (int __c, int __mask) __THROW;
87. #endif
88. #if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
89. /* 返回非0值,当且仅当C是ASCII字符集中(例如,不足7比特的宽度)  */
90. extern int isascii (int __c) __THROW;
91. /* 返回C中在ASCII字符集中的那部分(例如,C的低位7比特)  */
92. extern int toascii (int __c) __THROW;
93. /* 下面的原型与toupper和tolower相同,唯一不同的它们不检查实参是否在char
的范围内 */
94. __exctype (_toupper);
95. __exctype (_tolower);
96. #endif /* Use SVID or use misc.  */
97. /* 下面代码用于优化的转换函数中 */
98. #define __tobody(c, f, a, args) /
99.  (__extension__                                  /
100.    ({ int __res;                                  /
101.      if (sizeof (c) > 1)                              /
102.    {                                    /
103.      if (__builtin_constant_p (c))                      /
isalpha 函数
104.        {                                    /
105. int __c = (c);                              /
106.          __res = __c < -128 || __c > 255 ? __c : (a)[__c];            /
107.        }                                    /
108.      else                                    /
109.        __res = f args;                          /
110.    }                                    /
111.      else                                    /
112.    __res = (a)[(int) (c)];                          /
113.      __res; }))
114. #if !defined __NO_CTYPE && !defined __cplusplus
115. # define isalnum(c) __isctype((c), _ISalnum)
116. # define isalpha(c) __isctype((c), _ISalpha)
117. # define iscntrl(c) __isctype((c), _IScntrl)
118. # define isdigit(c) __isctype((c), _ISdigit)
119. # define islower(c) __isctype((c), _ISlower)
120. # define isgraph(c) __isctype((c), _ISgraph)
121. # define isprint(c) __isctype((c), _ISprint)
122. # define ispunct(c) __isctype((c), _ISpunct)
123. # define isspace(c) __isctype((c), _ISspace)
124. # define isupper(c) __isctype((c), _ISupper)
125. # define isxdigit(c)    __isctype((c), _ISxdigit)
126. # ifdef __USE_ISOC99
127. #  define isblank(c)    __isctype((c), _ISblank)
128. # endif
129. # ifdef __USE_EXTERN_INLINES
130. __extern_inline int
131. __NTH (tolower (int __c))
132. {
133.  return __c >= -128 && __c < 256 ? (*__ctype_tolower_loc ())[__c] : __c;  134. }
135. __extern_inline int
136. __NTH (toupper (int __c))
137. {
138.  return __c >= -128 && __c < 256 ? (*__ctype_toupper_loc ())[__c] : __c;  139. }
140. # endif
141. # if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus 142. #  define tolower(c)    __tobody (c, tolower, *__ctype_tolower_loc (), (c)) 143. #  define toupper(c)    __tobody (c, toupper, *__ctype_toupper_loc (), (c)) 144. # endif /* Optimizing gcc */
145. # if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPE N
146. #  define isascii(c)    __isascii (c)
147. #  define toascii(c)    __toascii (c)
148. #  define _tolower(c)  ((int) (*__ctype_tolower_loc ())[(int) (c)])

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。