Linux 字符类别判断

一般情况下判断一个字符为大写的方法用if 语句来判断,比如

[cpp]  view plain copy
  1. If (c>=’A’&&c<=’Z’) return true;  

小写的方法与之类似

因为字符A-Z,a-z在ASCII上是连续的,所以一个范围判断就可以了,假设某些字符在ASCII上是不连续的,比如十六进制数,0-9,A-H,那么if语句里面就需要两个范围判断了

[cpp]  view plain copy
  1. If((c>=’0’&&c<=’9’)||(c>=’A’&&c<=’H’)) return true;  

再者假设有更多的范围,那么if的条件部分就越长,判断条件长了,效率自然就低了。

    Linux中使用空间换时间的方法来做,基本方法为:

建立一个256个元素的unsigned char _ctypes[]全局数组,每一个数组元素的值代表其下标所对应的ASCII码的类别,比如大写字母A,其ASCII码为65,那么_ctypes[65]中的8个位代表了其所属类别,8个位最多有8中并列的属性。

在Linux中定义了8种属性,其宏为:

[cpp]  view plain copy
  1. #define _U      0x01   /* upper */  
  2.   
  3. #define_L      0x02    /* lower */  
  4.   
  5. #define_D      0x04    /* digit */  
  6.   
  7. #define_C      0x08    /* cntrl */  
  8.   
  9. #define_P      0x10    /* punct */  
  10.   
  11. #define_S      0x20    /* white space (space/lf/tab) */  
  12.   
  13. #define_X      0x40    /* hex digit */  
  14.   
  15. #define_SP     0x80    /* hard space (0x20) */   

Linux中将_ctypes初始化为:

[cpp]  view plain copy
  1. const unsigned char _ctype[]= {  
  2.   
  3.  _C,_C,_C,_C,_C,_C,_C,_C,                                /* 0-7 */  
  4.   
  5.  _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,                 /* 8-15 */  
  6.   
  7.  _C,_C,_C,_C,_C,_C,_C,_C,                                /* 16-23 */  
  8.   
  9.  _C,_C,_C,_C,_C,_C,_C,_C,                                /* 24-31 */  
  10.   
  11.  _S|_SP,_P,_P,_P,_P,_P,_P,_P,                            /* 32-39 */  
  12.   
  13.  _P,_P,_P,_P,_P,_P,_P,_P,                                /* 40-47 */  
  14.   
  15.  _D,_D,_D,_D,_D,_D,_D,_D,                                /* 48-55 */  
  16.   
  17.  _D,_D,_P,_P,_P,_P,_P,_P,                                /* 56-63 */  
  18.   
  19.  _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,              /* 64-71 */  
  20.   
  21.  _U,_U,_U,_U,_U,_U,_U,_U,                                /* 72-79 */  
  22.   
  23.  _U,_U,_U,_U,_U,_U,_U,_U,                                /* 80-87 */  
  24.   
  25.  _U,_U,_U,_P,_P,_P,_P,_P,                                /* 88-95 */  
  26.   
  27.  _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,              /* 96-103 */  
  28.   
  29.  _L,_L,_L,_L,_L,_L,_L,_L,                                /* 104-111 */  
  30.   
  31.  _L,_L,_L,_L,_L,_L,_L,_L,                                /* 112-119 */  
  32.   
  33.  _L,_L,_L,_P,_P,_P,_P,_C,                                /* 120-127 */  
  34.   
  35.  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                        /* 128-143 */  
  36.   
  37.  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                        /* 144-159 */  
  38.   
  39.  _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,    /* 160-175 */  
  40.   
  41.  _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,        /* 176-191 */  
  42.   
  43.  _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,        /* 192-207 */  
  44.   
  45.  _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,        /* 208-223 */  
  46.   
  47.  _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,        /* 224-239 */  
  48.   
  49.  _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};       /* 240-255 */  

然后Linux定义了一个宏:

[cpp]  view plain copy
  1. #define __ismask(x)(_ctype[(int)(unsigned char)(x)])  

此宏获得一个字符所对应数组中的标志值,

Linux中又定义了一些宏用以辅助判断一个字符类别:

[cpp]  view plain copy
  1. #define isalnum(c)      ((__ismask(c)&(_U|_L|_D)) != 0)       //大写,小写,数字  
  2. #define isalpha(c)      ((__ismask(c)&(_U|_L)) != 0)          //大写,小写  
  3. #define iscntrl(c)      ((__ismask(c)&(_C)) != 0)             //控制  
  4. #define isdigit(c)      ((__ismask(c)&(_D)) != 0)             //数字  
  5. #define isgraph(c)      ((__ismask(c)&(_P|_U|_L|_D)) != 0)    //字符是否图形  
  6. #define islower(c)      ((__ismask(c)&(_L)) != 0)             //是否小写     
  7. #define isprint(c)      ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)//是否可打印  
  8. #define ispunct(c)      ((__ismask(c)&(_P)) != 0)             /* punct */  
  9. /* Note: isspace() must return false for %NUL-terminator */  
  10. #define isspace(c)      ((__ismask(c)&(_S)) != 0)             /*(space/lf/tab) */  
  11. #define isupper(c)      ((__ismask(c)&(_U)) != 0)             //是否大写  
  12. #define isxdigit(c)     ((__ismask(c)&(_D|_X)) != 0)          //是否十六进制数  
  13. #define isascii(c) (((unsigned char)(c))<=0x7f)               //是否ASCII  
  14. #define toascii(c) (((unsigned char)(c))&0x7f)                //转为ASCII  

上述宏在程序中可以直接使用了,比如想判断某个字符是否为大写

[cpp]  view plain copy
  1. If (isupper(‘A’)) return true;  
  2.   
  3. If (isxdigit(‘B’)) return true;  


比如:

[cpp]  view plain copy
  1. static inline unsigned char __tolower(unsigned char c)//转为小写字母  
  2.  {  
  3.           if (isupper(c))  
  4.                   c -= 'A'-'a';  
  5.          return c;  
  6.   }  
  7.  static inline unsigned char __toupper(unsigned char c)//转为大写字母  
  8.  {  
  9.          if (islower(c))  
  10.                  c -= 'a'-'A';  
  11.          return c;  
  12.  }  


Linux中方法已经描述完了,下面对比优劣。

  普通方法:

      优势:简单易懂,不额外占用数据空间

      劣势:效率较第二种低,需要很多条件判断指令

  Linux方法:

      优势:速度快,一次性位操作即可完成任务,优雅。

      劣势:额外的占用了空间。

    综合:

        如果自己随便写个小小程序的话,第一种方法够用了。如果是一个真实的项目的,推荐第二种方法。


转载:http://blog.csdn.net/panweiguozhou/article/details/6831232




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值