您的位置:首页 > 其它

C标准库函数实现之字符串比较函数

2011-11-02 09:56 197 查看
今天看C标准库,有个比较相关的系列函数,看到了两个不认识的函数,strcoll和strxfrm。

首先来看strcoll函数,原型为:int strcoll(const char *s1, const char *s2);

按照说明,这个函数是用来比较串的,那作用应该和strcmp差不多,但是它的作用不止于此,“若LC_COLLATE为"POSIX"或"C",则strcoll()与strcmp()作用完全相同”,那也就是说,当LC_COLLATE为其它值的时候,strcoll与strcmp作用是不同的。在这篇文章中(http://www.diybl.com/course/3_program/c++/cppsl/20081117/151299.html),就有介绍使用setlocale函数设置本地化后,strcoll函数会表现出与strcmp不同的特性。

看到这个函数的时候,想到了它的安全问题,应该是很容易缓冲区溢出的。所以尽量还是不要使用这个函数。

strxfrm,看起来很奇怪的一个函数,原型为:size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n); 功能是将s2中的前n个字符存储到s1中,那么返回值是什么呢?看代码,摘自Minix 3

size_t strxfrm(register char *s1, register const char *save, register size_t n)
{
register const char *s2 = save;

while (*s2) {
if (n > 1) {
n--;
*s1++ = *s2++;
} else
s2++;
}
if (n > 0)
*s1++ = '\0';
return s2 - save;
}
思路如下:

*s2不为0时,若n>1,则不断地copy,n自减;否则s2不断前移当*s2为0时,说明已经到了s2结尾处,若此时n>0时,则将*s1赋值为'\0‘.这里按照代码的意思,形参n,包括了s1的结束符'\0'。对于返回值,是s2-save的长度。但是由于无论如何s2都会执行到最后一个为'\0’的结束符,所以返回的应该是字串save的长度
对于这个函数的实现,我还是感到相当奇怪的……以上代码摘自minix 3.1.1,貌似真正按字符算的话,只拷了n-1个字符过去了。遂决定验证一番,代码如下:

#include <stdio.h>
#include <string.h>

int strxfrm2(char* s1 , char* s2 , int n)
{
char* s = s2;
while(*s){
if (n>1){
n--;
*s1++ = *s++;
}
else
s++;
}
if (n>0)
*s1++ = 0;
return s - s2;
}

void main()
{
char  s1[20] = {0};
char* s2 = "Welcome to beijing";
printf("string length is %d\n" , strlen(s2));
printf("strxfrm2 return value is %d\n",strxfrm2(s1,s2,6));
printf("s1 is %s\n",s1);
memset(s1,0,20);
printf("strxfrm return value is %d\n",strxfrm(s1,s2,6));
printf("s1 is %s\n",s1);
return;
}


这里strxfrm是标准库中的函数,strxfrm2是使用的minix中的strxfrm函数的实现,编译器使用gcc,输出的结果是:


string length is 18
strxfrm2 return value is 18
s1 is Welco
strxfrm return value is 18
s1 is Welcom



额……这是个很让人无语的结果,目的字符串的值不同,为什么标准库的函数实现不同呢?难道是因为标准不同的原因?我也不知道……要去问下minix的实现者了o(╯□╰)o

题外话………貌似strxfrm不是字符串比较函数啊……归类在comparison function里面…我倒……求解释
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: