亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > .NET > 正文

C標準庫源碼解剖(3):字符處理函數ctype.h和wctype.h

2024-07-10 13:27:14
字體:
來源:轉載
供稿:網友

 字符處理包括分類(即屬性判斷)和轉換函數。ASCII字符主要可分類為控制字符、空白字符、可打印字符、數字字符、字母字符(大寫和小寫)、標點符號等。
    1、ctype.h: 標準的屬性判斷函數有isalnum,isalpha,iscntrl,isdigit,isxdigit,isgraph,isprint,ispunct,islower,isupper,isspace, isblank(C99中引入)共12個函數。標準的屬性轉換函數有tolower和toupper。當然具體的實現中還會提供一些非標準函數作為擴展,如glibc的實現中提供了isctype,isascii,toascii。

 

[cpp] view plaincopy
  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))                       /  
  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_XOPEN  
  146. #  define isascii(c)    __isascii (c)  
  147. #  define toascii(c)    __toascii (c)  
  148. #  define _tolower(c)   ((int) (*__ctype_tolower_loc ())[(int) (c)])  
  149. #  define _toupper(c)   ((int) (*__ctype_toupper_loc ())[(int) (c)])  
  150. # endif  
  151. #endif /* Not __NO_CTYPE.  */  
  152. /* 下面是GNU對各個屬性分類函數和轉換函數的擴展接口,每個函數有一個對應的擴展版本, 
  153.     增加了一個參數用來傳遞區域設置 */  
  154.       
  155. /* ...... */  
  156. __END_DECLS  
  157. #endif /* ctype.h  */  

 

 

[cpp] view plaincopy
  1. /* ctype.c:各個字符處理函數的實現  */  
  2. #define __NO_CTYPE  
  3. #include <ctype.h>  
  4. /* 為所有的ctype宏提供實際的函數實現  */  
  5. #define func(name, type) /  
  6.   int name (int c) { return __isctype (c, type); }  
  7. func (isalnum, _ISalnum)  
  8. func (isalpha, _ISalpha)  
  9. func (iscntrl, _IScntrl)  
  10. func (isdigit, _ISdigit)  
  11. func (islower, _ISlower)  
  12. func (isgraph, _ISgraph)  
  13. func (isprint, _ISprint)  
  14. func (ispunct, _ISpunct)  
  15. func (isspace, _ISspace)  
  16. func (isupper, _ISupper)  
  17. func (isxdigit, _ISxdigit)  
  18. #define __ctype_tolower /  
  19.   ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOLOWER) + 128)  
  20. #define __ctype_toupper /  
  21.   ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOUPPER) + 128)  
  22. int  
  23. tolower (int c)  
  24. {  
  25.   return c >= -128 && c < 256 ? __ctype_tolower[c] : c;  
  26. }  
  27. int  
  28. toupper (int c)  
  29. {  
  30.   return c >= -128 && c < 256 ? __ctype_toupper[c] : c;  
  31. }  

 

    解釋:
    (1)字符的所有屬性類被封裝在一個enum中,每個屬性對應一個枚舉常量。
    (2)在作為接口的頭文件中,由于各個函數的類型相同,都接受int型字符,返回int型的值,因此原型聲明可用宏__exctype(name)來完成,name為函數名,這樣可以簡化代碼。
    (3)所有的屬性判斷函數的實現都是用宏__isctype(c, type)和返回數組指針的外部函數__ctype_b_loc()來完成。在實現文件ctype.c中可以看到,所有的判斷函數都只有一條語句“return __isctype (c, type);”。這個函數式宏用來判斷字符c是否具有屬性type(為枚舉常量),它直接以字符c為下標,獲得__ctype_b_loc()數組相應位置處的元素,并與屬性作邏輯與運算,若結果為非0,說明字符具有該屬性,若結果為0則說明字符沒有該屬性。__ctype_b_loc()函數在glibc庫的ctype-info.c文件中定義,它直接使用了glibc 2.0中已經實現的內置函數??梢?,這里用宏來實現ctype,使之可以擴展,增加任意的屬性。當然,我們也可以自己來實現這些屬性函數,代碼都很簡單,只要判斷其ASCII編碼范圍即可。
    (4)ctype.c中的tolower和toupper函數實現使用了宏__ctype_tolower,這個宏會被映射成一個數組。它直接根據字符c的范圍__ctype_tolower[c]或c本身。
    (5)ctype.h下面的優化實現用于需要優化的環境中(比如用帶優化選項的gcc來編譯)。它直接把屬性判斷函數定義為宏,宏體就是__isctype (c, type)。定義成宏時就少了一層函數調用。tolower和toupper根據需要,或者用外部函數__ctype_tolower_loc()和__ctype_toupper_loc()來實現,并實現成內聯函數;或者直接定義成宏,用這里定義的__tobody(c, f, a, args)來實現。這兩者都差不多,因為內聯函數也相當于具有宏的特征。
    (6)__BEGIN_DECLS/__END_DECLS宏用來表示數據結構、全局變量、函數原型聲明的開始和結束。這類似于MFC中的BEGIN_MESSAGE_MAP/END_MESSAGE_MAP。__BEGIN_NAMESPACE_STD/__END_NAMESPACE_STD宏表示C標準庫函數原型聲明的開始和結束。__BEGIN_NAMESPACE_C99/__END_NAMESPACE_C99表示C99標準中的函數聲明。
   2、wctype.h: C89增補1中引入,是ctype.h中各個函數的寬字符處理版本,能對寬字符進行屬性分類和轉換。還定義了通用屬性類型wctype_t,表示字符轉換的類型wctrans_t,構造屬性的函數wctype,測試屬性的通用函數iswctype,構造轉換的函數wctrans,實行轉換的通用函數towctrans。

[cpp] view plaincopy
  1. /* ISO C99 Standard: 7.25  寬字符分類和轉換函數   <wctype.h>  */  
  2. #ifndef _WCTYPE_H  
  3. #include <features.h>  
  4. #include <bits/types.h>  
  5. #ifndef __need_iswxxx  
  6. # define _WCTYPE_H  1  
  7. /* 從<wchar.h>中獲取wint_t類型  */  
  8. # define __need_wint_t  
  9. # include <wchar.h>  
  10. /* wint_t類型的常量表達式,其值不是擴展字符集的任何成員 */  
  11. # ifndef WEOF  
  12. #  define WEOF (0xffffffffu)  
  13. # endif  
  14. #endif  
  15. #undef __need_iswxxx  
  16. /* 當<wcsmbs.h>在Unix98兼容的代碼中使用時,下面部分也會在<wcsmbs.h>頭文件中被使用 */  
  17. #ifndef __iswxxx_defined  
  18. # define __iswxxx_defined   1  
  19. __BEGIN_NAMESPACE_C99  
  20. /* 標量類型,該類型的值表示特定區域字符的分類 */  
  21. typedef unsigned long int wctype_t;   
  22. __END_NAMESPACE_C99  
  23. # ifndef _ISwbit  
  24. /* 這些屬性總是被存儲為網絡字節序(大端字節)。我們為每個屬性定義一個 
  25.     依賴于機器字節序的比特位解釋 */  
  26. #  include <endian.h>  
  27. #  if __BYTE_ORDER == __BIG_ENDIAN  
  28. #   define _ISwbit(bit) (1 << (bit))  
  29. #  else /* 否則__BYTE_ORDER==__LITTLE_ENDIAN,是小端字節序 */  
  30. #   define _ISwbit(bit) /  
  31.     ((bit) < 8 ? (int) ((1UL << (bit)) << 24)                  /  
  32.      : ((bit) < 16 ? (int) ((1UL << (bit)) << 8)               /  
  33.         : ((bit) < 24 ? (int) ((1UL << (bit)) >> 8)                /  
  34.            : (int) ((1UL << (bit)) >> 24))))  
  35. #  endif  
  36. enum  
  37. {  
  38.   __ISwupper = 0,           /* 大寫寬字符 */  
  39.   __ISwlower = 1,           /* 小寫寬字符  */  
  40.   __ISwalpha = 2,           /* 字母寬字符  */  
  41.   __ISwdigit = 3,           /* 十進制數字寬字符  */  
  42.   __ISwxdigit = 4,          /* 十六進制數字寬字符  */  
  43.   __ISwspace = 5,           /* 空白寬字符  */  
  44.   __ISwprint = 6,           /* 可打印寬字符  */  
  45.   __ISwgraph = 7,           /* 圖形寬字符  */  
  46.   __ISwblank = 8,           /* 空白分隔寬字符:通常是空格符和水平制表符(Space和Tab鍵)  */  
  47.   __ISwcntrl = 9,           /* 控制寬字符  */  
  48.   __ISwpunct = 10,          /* 標點符號寬字符  */  
  49.   __ISwalnum = 11,          /* 字母和數字寬字符  */  
  50.   _ISwupper = _ISwbit (__ISwupper), /* UPPERCASE.  */  
  51.   _ISwlower = _ISwbit (__ISwlower), /* lowercase.  */  
  52.   _ISwalpha = _ISwbit (__ISwalpha), /* Alphabetic.  */  
  53.   _ISwdigit = _ISwbit (__ISwdigit), /* Numeric.  */  
  54.   _ISwxdigit = _ISwbit (__ISwxdigit),   /* Hexadecimal numeric.  */  
  55.   _ISwspace = _ISwbit (__ISwspace), /* Whitespace.  */  
  56.   _ISwprint = _ISwbit (__ISwprint), /* Printing.  */  
  57.   _ISwgraph = _ISwbit (__ISwgraph), /* Graphical.  */  
  58.   _ISwblank = _ISwbit (__ISwblank), /* Blank (usually SPC and TAB).  */  
  59.   _ISwcntrl = _ISwbit (__ISwcntrl), /* Control character.  */  
  60.   _ISwpunct = _ISwbit (__ISwpunct), /* Punctuation.  */  
  61.   _ISwalnum = _ISwbit (__ISwalnum)  /* Alphanumeric.  */  
  62. };  
  63. # endif /* Not _ISwbit  */  
  64.   
  65. __BEGIN_DECLS  
  66. __BEGIN_NAMESPACE_C99  
  67. /* 
  68.  * 寬字符分類函數: 7.15.2.1. 
  69.  */  
  70. /* 測試c是否是字母或數字寬字符,等價于iswalpha(c) || iswdigit(c) */  
  71. extern int iswalnum (wint_t __wc) __THROW;  
  72. /* 測試c是否是特定區域設置的字母寬字符,在iswlower(c)或isupper(c)為真時取值為真, 
  73.     在iswcntrl(c),iswdigit(c),iswpunct(c)或iswspace(c)為真時取值為假 */  
  74. extern int iswalpha (wint_t __wc) __THROW;  
  75. /* 測試是否是控制型的寬字符  */  
  76. extern int iswcntrl (wint_t __wc) __THROW;  
  77. /* 測試是否是十進制的數字寬字符  */  
  78. extern int iswdigit (wint_t __wc) __THROW;  
  79. /* 測試是否是圖形寬字符,等價于iswprint(c) && !iswspace(c)  */  
  80. extern int iswgraph (wint_t __wc) __THROW;  
  81. /* 測試是否是小寫寬字符,等價于!iswcntrl(c) && !iswdigit(c) && !iswpunct(c)  
  82.    && !iswspace(c) */  
  83. extern int iswlower (wint_t __wc) __THROW;  
  84. /* 測試是否是可打印寬字符  */  
  85. extern int iswprint (wint_t __wc) __THROW;  
  86. /* 測試是否是標點符號寬字符,等價于iswprint(c) && !iswalnum(c) && !iswspace(c)  */  
  87. extern int iswpunct (wint_t __wc) __THROW;  
  88. /* 測試是否是空白寬字符,等價于!iswalnum(c) && !iswgraph(c) && !ispunct(c)  */  
  89. extern int iswspace (wint_t __wc) __THROW;  
  90. /* 測試是否是大寫寬字符,等價于!iswcntrl(c) && !iswdigit(c) && !iswpunct(c)  
  91.    && !iswspace(c) */  
  92. extern int iswupper (wint_t __wc) __THROW;  
  93. /* 測試是否是十六進制的數字寬字符  */  
  94. extern int iswxdigit (wint_t __wc) __THROW;  
  95. /* 測試是否是空白分隔寬字符  */  
  96. # ifdef __USE_ISOC99  
  97. extern int iswblank (wint_t __wc) __THROW;  
  98. # endif  
  99. /* 
  100.  * 可擴展的寬字符分類函數: 7.15.2.2. 
  101.  */  
  102. /* 構造一個wctype_t類型的值,表示由字符串PROPERTY標識的寬字符類 */  
  103. extern wctype_t wctype (__const char *__property) __THROW;  
  104. /* 確定寬字符WC是否是DESC所標識的寬字符類 */  
  105. extern int iswctype (wint_t __wc, wctype_t __desc) __THROW;  
  106. __END_NAMESPACE_C99  
  107. /* 
  108.  * 寬字符的大小寫轉換函數: 7.15.3.1. 
  109.  */  
  110. __BEGIN_NAMESPACE_C99  
  111. /* 標量類型,該類型的值表示特定區域的寬字符轉換 */  
  112. typedef __const __int32_t *wctrans_t;  
  113. __END_NAMESPACE_C99  
  114. #ifdef __USE_GNU  
  115. __USING_NAMESPACE_C99(wctrans_t)  
  116. #endif  
  117. __BEGIN_NAMESPACE_C99  
  118. /* 把大寫寬字符轉換成對應的小寫寬字符  */  
  119. extern wint_t towlower (wint_t __wc) __THROW;  
  120. /* 把小寫寬字符成對應的大寫寬字符 */  
  121. extern wint_t towupper (wint_t __wc) __THROW;  
  122. __END_NAMESPACE_C99  
  123. __END_DECLS  
  124. #endif  /* need iswxxx.  */  
  125.   
  126. /* 剩下的定義和聲明一定不能出現在<wcsmbs.h>中 */  
  127. #ifdef _WCTYPE_H  
  128. /* 
  129.  * 可擴展的寬字符轉換函數: 7.15.3.2. 
  130.  */  
  131. __BEGIN_DECLS  
  132. __BEGIN_NAMESPACE_C99  
  133. /* 構造一個wctrans_t類型的值,表示由字符串PROPERTY標識的寬字符轉換 */  
  134. extern wctrans_t wctrans (__const char *__property) __THROW;  
  135. /* 使用DESC所示的轉換來對寬字符WC進行轉換 */  
  136. extern wint_t towctrans (wint_t __wc, wctrans_t __desc) __THROW;  
  137. __END_NAMESPACE_C99  
  138. /* 下面是GNU對各個分類函數和轉換函數的擴展接口,每個函數有一個對應的擴展版本, 
  139.     增加了一個參數用來傳遞區域設置 */  
  140.       
  141. /* ...... */  
  142. __END_DECLS  
  143. #endif  /* __WCTYPE_H defined.  */  
  144. #endif /* wctype.h  */  

 

 

[cpp] view plaincopy
  1. /* wcfuncs.c:各個寬字符處理函數的實現 */  
  2. #include <ctype.h>  
  3. #include <wctype.h>  
  4. #include <locale/localeinfo.h>  
  5. #include "wchar-lookup.h"  
  6. /* 為所有wctype的原型提供實際的函數實現  */  
  7. #define func(name, type)                              /  
  8.   extern int __isw##name (wint_t __wc);                       /  
  9.   int                                         /  
  10.   __isw##name (wint_t wc)                             /  
  11.   {                                       /  
  12.     if (isascii (wc))                                 /  
  13.       return is##name ((int) wc);                         /  
  14.     size_t i = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_CLASS_OFFSET) + type;    /  
  15.     const char *desc = _NL_CURRENT (LC_CTYPE, i);                 /  
  16.     return wctype_table_lookup (desc, wc);                    /  
  17.   }                                       /  
  18.   weak_alias (__isw##name, isw##name)  
  19. #undef iswalnum  
  20. func (alnum, __ISwalnum)  
  21. libc_hidden_weak (iswalnum)  
  22. #undef iswalpha  
  23. func (alpha, __ISwalpha)  
  24. libc_hidden_weak (iswalpha)  
  25. #undef iswblank  
  26. func (blank, __ISwblank)  
  27. #undef iswcntrl  
  28. func (cntrl, __ISwcntrl)  
  29. #undef iswdigit  
  30. func (digit, __ISwdigit)  
  31. libc_hidden_weak (iswdigit)  
  32. #undef iswlower  
  33. func (lower, __ISwlower)  
  34. libc_hidden_weak (iswlower)  
  35. #undef iswgraph  
  36. func (graph, __ISwgraph)  
  37. #undef iswprint  
  38. func (print, __ISwprint)  
  39. #undef iswpunct  
  40. func (punct, __ISwpunct)  
  41. #undef iswspace  
  42. func (space, __ISwspace)  
  43. libc_hidden_weak (iswspace)  
  44. #undef iswupper  
  45. func (upper, __ISwupper)  
  46. #undef iswxdigit  
  47. func (xdigit, __ISwxdigit)  
  48. libc_hidden_weak (iswxdigit)  
  49. #undef towlower  
  50. /* towlower函數的實現 */  
  51. wint_t  
  52. towlower (wc)  
  53.      wint_t wc;  
  54. {  
  55.   /* 獲取區域設置表中當前區域類別的索引 */  
  56.   size_t i = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_OFFSET) + __TOW_tolower;  
  57.   /* 根據索引,獲取當前區域設置類別的描述字符串 */  
  58.   const char *desc = _NL_CURRENT (LC_CTYPE, i);  
  59.   return wctrans_table_lookup (desc, wc); /* 搜索位表,以獲得轉換后的寬字符,并返回 */  
  60. }  
  61. libc_hidden_def (towlower)  
  62. #undef towupper  
  63. /* towupper函數的實現 */  
  64. wint_t  
  65. towupper (wc)  
  66.      wint_t wc;  
  67. {  
  68.   /* 獲取區域設置表中當前區域類別的索引 */  
  69.   size_t i = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_OFFSET) + __TOW_toupper;  
  70.   /* 根據索引,獲取當前區域設置類別的描述字符串 */  
  71.   const char *desc = _NL_CURRENT (LC_CTYPE, i);  
  72.   return wctrans_table_lookup (desc, wc); /* 搜索位表,以獲得轉換后的寬字符,并返回 */  
  73. }  
  74. libc_hidden_def (towupper)  

 

   解釋:
   (1)wctype.h的實現更通用,它定義一個描述寬字符屬性的類型wctype_t,為unsigned long標量類型,實現了可擴展的、特定區域設置的寬字符分類功能。同樣它也把所有屬性類封裝在一個enum中,每個屬性對應一個枚舉常量。wctype函數用來構造一個字符屬性,參數為標識這個屬性的字符串,主要有"alnum"、"alpha"、 "cntrl"、"digit"、"graph"、"lower"、"print"等,對應iswxxx屬性分類函數。iswctype函數測試寬字符WC是否屬于DESC屬性類。調用iswctype時LC_CTYPE類別的設置應與wctype構造desc值時的LC_CTYPE設置相同。
   (2)寬字符集的分類取決于區域設置,其標準屬性類映射到ASCII中的關系要理清楚:
   字母或數字 = 字母 || 數字
   大(小)寫字母 = !控制字符 && !數字 && !標點符號 && !空白字符
   字母 = (大寫字母 || 小寫字母) && !控制字符 && !數字 && !標點符號 && !空白字符   
   圖形字符 = 可打印字符 && !空格
   標點符號 = 可打印字符 && !字母 && !數字 && !空白字符
   空白字符 = !字母 && !數字 && !圖形字符 && !標點符號
   (3)對字符屬性的轉換,wctype.h也定義了一個描述寬字符轉換的類型wctrans_t,為32位整型指針。wctrans函數用來構造一個字符轉換,參數為標識這個轉換的字符串,主要有"tolower"、"toupper",對應towxxx轉換函數,這個轉換針對當前區域設置的LC_CTYPE類別值。towctrans函數使用DESC所示的轉換來對寬字符WC進行轉換。
   (4)在函數實現文件wcfuncs.c中,同樣用了一個宏func(name, type)來簡化實現。實現代碼主要用到了_NL_CURRENT_WORD宏、LC_CTYPE類別宏、NL_CTYPE_MAP_OFFSET偏移宏。這些宏的功能在編譯器內部或其附帶的庫中實現了。wctrans_table_lookup函數在wchar-lookup.h中定義,用于查詢映射表,以獲得轉換后的寬字符。映射表有點類似于Unix的文件結構,用32位的字作為下標索引。寬字符集的每個字符被切割成4個比特塊存儲在位表的前面表項中,后面的幾個表項存放了一級子表、二級子表、以及三級子表的指針。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产视频一区在线| 欧美成人免费大片| 欧美第一淫aaasss性| 日韩中文综合网| 在线播放国产一区中文字幕剧情欧美| 中文字幕一精品亚洲无线一区| 91在线直播亚洲| 岛国av一区二区在线在线观看| 精品视频—区二区三区免费| 欧美与黑人午夜性猛交久久久| 91免费视频国产| 亚洲欧美精品一区二区| 亚洲精美色品网站| 欧美激情第6页| 97免费在线视频| 欧美激情在线观看| 欧美伦理91i| 欧美性xxxxx| 日韩欧美国产网站| 久久久综合免费视频| 亚洲欧美日韩国产精品| 岛国av一区二区在线在线观看| 久久99青青精品免费观看| 亚洲免费视频网站| 久久九九全国免费精品观看| 精品久久久久久中文字幕| 精品中文字幕在线2019| 欧美另类精品xxxx孕妇| 国产精品美女免费视频| 国产精品白嫩初高中害羞小美女| 最新的欧美黄色| 欧美激情在线播放| 午夜精品福利视频| 国产日韩在线视频| 国产欧美亚洲精品| 伊人亚洲福利一区二区三区| 成人天堂噜噜噜| 成人黄色av免费在线观看| 亚洲欧美日韩精品| 亚洲欧美日韩中文在线制服| 久久全国免费视频| 亚洲美女精品成人在线视频| 国产精品三级美女白浆呻吟| 欧美理论电影网| 成人在线小视频| 亚洲欧洲美洲在线综合| 青青在线视频一区二区三区| 亚洲天堂av在线免费| 91精品视频观看| 欧美日韩国产精品| 亚洲欧美综合精品久久成人| 欧美性xxxxx极品娇小| 日本精品va在线观看| 亚洲一区中文字幕在线观看| 欧美极品少妇xxxxⅹ免费视频| 欧美激情精品久久久久久黑人| 国产精品com| 国产精品露脸av在线| 欧美色欧美亚洲高清在线视频| 欧美在线观看一区二区三区| 亚洲欧美制服丝袜| 亚洲全黄一级网站| 正在播放欧美一区| 狠狠躁夜夜躁久久躁别揉| 欧美性在线观看| 亚洲电影免费观看高清完整版在线观看| 久久久噜噜噜久噜久久| 精品亚洲国产成av人片传媒| 亚洲第一av网| 国产精品www网站| 浅井舞香一区二区| 精品国产区一区二区三区在线观看| 久久久久九九九九| 国产精品久久久久av| 久久久久久久久电影| 2023亚洲男人天堂| 在线丨暗呦小u女国产精品| 亚洲欧美日韩在线高清直播| 最近2019中文字幕mv免费看| 欧美香蕉大胸在线视频观看| 91精品国产高清久久久久久久久| 久久久精品国产亚洲| 国产精品一区久久| 欲色天天网综合久久| 午夜免费日韩视频| 日本最新高清不卡中文字幕| 欧美一级高清免费| 国产成人精品视频| 日韩av片电影专区| 777午夜精品福利在线观看| 九九九热精品免费视频观看网站| 国产精品流白浆视频| 亚洲精品久久久久久久久久久| 亚洲欧美日韩一区二区三区在线| 国产成人午夜视频网址| 国产主播欧美精品| 国产精品视频公开费视频| 77777少妇光屁股久久一区| 日韩av中文字幕在线免费观看| 91精品啪在线观看麻豆免费| 国产精品一区二区性色av| 性欧美亚洲xxxx乳在线观看| 91免费精品国偷自产在线| 亚洲精品资源美女情侣酒店| 中文字幕亚洲国产| 久久国产精品视频| 欧美影院成年免费版| 北条麻妃一区二区三区中文字幕| 亚洲第一级黄色片| 久久久久久久久久久成人| 日本成熟性欧美| 精品成人69xx.xyz| 欧美在线www| 国产成人福利夜色影视| 亚洲精品www久久久| 日韩有码片在线观看| 国产激情久久久久| 91性高湖久久久久久久久_久久99| 国产精品老女人精品视频| 欧美在线视频免费观看| 自拍偷拍亚洲精品| 色综合91久久精品中文字幕| 欧美精品videosex极品1| 欧洲亚洲妇女av| 亚洲自拍偷拍福利| 精品亚洲一区二区三区在线观看| 日韩美女在线观看| 日韩av在线免播放器| 欧美巨猛xxxx猛交黑人97人| 欧美日韩美女视频| 国产欧美久久一区二区| 97在线观看视频国产| 亚洲成人a**站| 国产精品视频大全| 黄色一区二区三区| 91理论片午午论夜理片久久| 久久精品国产清自在天天线| 欧美成人一区二区三区电影| 亚洲性夜色噜噜噜7777| 欧美丰满少妇xxxxx做受| 在线观看国产精品91| 中文字幕亚洲欧美日韩2019| 精品亚洲男同gayvideo网站| 日韩高清电影好看的电视剧电影| 国产日韩欧美夫妻视频在线观看| 国产在线观看精品| 国产成人久久久精品一区| 欧美激情视频一区二区三区不卡| 国产91色在线免费| 亚洲欧美国产精品va在线观看| 国产精品视频区1| 国产精品一二三视频| 亚洲精品电影网| 欧美一级电影免费在线观看| 91wwwcom在线观看| 国产精品青青在线观看爽香蕉| 国产精品视频久久| 久久综合九色九九| 亚洲欧美日韩在线高清直播| 亚洲国产精品va| 欧美精品在线第一页| 欧美日韩免费在线| 日韩在线精品视频| 欧美日韩在线影院|