Linux 字符类别判断

来源:互联网 发布:windows nt是什么 编辑:程序博客网 时间:2024/05/21 22:49

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

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

小写的方法与之类似

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

[cpp] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  1. #define __ismask(x)(_ctype[(int)(unsigned char)(x)])  

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

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

[cpp] view plaincopy
  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 plaincopy
  1. If (isupper(‘A’)) return true;  
  2.   
  3. If (isxdigit(‘B’)) return true;  


比如:

[cpp] view plaincopy
  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




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 高中的孩子不爱学习怎么办 9个月宝宝肠胃不好怎么办 孩子高烧过后干呕不爱吃饭怎么办 母乳涨奶发烧了怎么办 涨奶发烧了怎么办啊 2岁宝贝不吃饭怎么办 4个月的婴儿厌食怎么办 2个月婴儿厌食怎么办 3个月宝宝厌奶怎么办 没胃口吃不下饭怎么办 小孩吃多了积食怎么办 孩子吃撑了难受怎么办 卵巢早衰月经量少怎么办 7岁孩吃饭少消瘦怎么办 宝宝3岁不吃饭怎么办 小孩吃多了吐了怎么办 6岁儿童越来越瘦怎么办 7岁儿童不吃饭怎么办 天热宝宝不好好吃饭怎么办 天热宝宝不爱吃饭怎么办 天热宝宝不想吃饭怎么办 夏天天热宝宝不爱吃饭怎么办 3岁宝宝吃饭不香怎么办 胃ca吃饭反胃没食欲怎么办 12岁儿童脸色发黄怎么办 胃饿 但是没食欲不想吃饭怎么办 牙缝大经常塞西怎么办 吃肉老是塞牙缝怎么办 宝宝光喝奶粉不吃饭怎么办 九个月宝宝缺维c怎么办 九个月宝宝缺维d怎么办 9个月大宝宝缺锌怎么办 三周岁宝宝不爱吃饭怎么办 一周岁宝宝不爱吃饭怎么办 两岁半宝宝不自己吃饭怎么办 3岁宝宝不会吃饭怎么办 节食减肥胃疼怎么办呢 减肥不吃饭胃疼怎么办 过度节食伤了胃怎么办 3岁宝宝啥也不吃怎么办 1岁多宝宝不吃饭怎么办