EricYang

Tech Spot of Eric

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

字符串比较函数,这个函数也比较常用:

view plaincopy to clipboardprint?
int strcmp(const char* str1,const char* str2){   
    assert(str1!=NULL&&str2!=NULL);   
    while(*str1&&*str2&&*str1==*str2){   
        str1++;   
        str2++;   
    }   
    if(*str1==*str2&&*str1==0)   
        return 0;//equal   
    else if(*str1<*str2)   
        return -1;   
    else  
        return 1;   
}  
int strcmp(const char* str1,const char* str2){
 assert(str1!=NULL&&str2!=NULL);
 while(*str1&&*str2&&*str1==*str2){
  str1++;
  str2++;
 }
 if(*str1==*str2&&*str1==0)
  return 0;//equal
 else if(*str1<*str2)
  return -1;
 else
  return 1;
}

看看上面代码有问题吗?

乍看,这个程序思路非常清楚,应该没什么问题的,是这样吗?在我们能尝试的一些字符串中这个函数是的确没问题的,而且在VC上拿它和string.h中的strcmp函数进行比较,发现两个函数每次的结果都是一样的。而我们往往遗忘了一种情况:如果一个字符值的ASCII码值超过127,该如何比较?也就是说,这类字符是非常规、不常用的字符。如果采用上面的方法,会得到相反的结果。如字符¥的ASCII码值在850 (Latin 1)为190,将其和"a"比较,上面的代码得到的结果是-1;而使用标准库函数得到的结果是1。理论上讲,ASCII值大的应该返回1,而上面程序刚好相反。

具体原因在于,对于超过127的字符在使用上面的函数时(默认上代码中实际也都是这么处理的)将该字符串视为符号(signed)的字符串,所以超过127的字符或按照对应的2进制补码转换为对应的负数,从而产生上面错误的结果。如¥所存的值为190-256=-66,-66<97,所以程序判断¥<a,返回-1。所以在处理时应该统一将其转换为对应的无符号型,下面代码参考微软VC6.0中对应的strcmp部分代码,正是进行了这种转换:

 1 int strcmp(const char* str1,const char* str2)
 2 {   
 3     int ret=0;   
 4     while((ret=*(unsigned char *)str1-*(unsigned char *)str2)==0&&*str2)   
 5         str1++;str2++;   
 6     if(ret==0)   
 7         return 0;   
 8     else if(ret<0)   
 9         return -1;   
10     else  
11         return 1;   
12 } 
posted on 2012-08-15 23:17  Eric-Yang  阅读(754)  评论(0编辑  收藏  举报