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
这里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里面…我倒……求解释
首先来看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里面…我倒……求解释
相关文章推荐
- 写一个函数,实现两个字符串的比较。即实现strcmp函数,s1=s2时返回0,s1!=s2时返回二者第一个不同字符的ASCII值。
- 实现字符串拷贝strcpy和memcpy,以及字符串比较函数strcmp
- 字符串逻辑比较函数---StrCmpLogicalW的模拟实现
- 字符串逻辑比较函数---StrCmpLogicalW的模拟实现
- 字符串比较函数原型实现
- 字符串逻辑比较函数---StrCmpLogicalW的模拟实现
- 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数
- 字符串比较和复制(函数实现)
- 自己实现基本的C标准库字符串处理函数——实现strcpy
- 模拟实现字符串比较函数:strcmp
- 字符串拷贝函数和字符串比较函数C语言实现方法
- 实现strcmp函数功能--比较字符串
- c++ 如何用一个函数实现两个字符串的比较
- 指针实现字符串比较函数strcmp
- 字符串拷贝函数和字符串比较函数C语言实现方法
- 自己实现基本的C标准库字符串处理函数——基本问题
- 自己实现基本的C标准库字符串处理函数——基本问题(转载)
- 编写一个函数,实现两个字符串的比较,即自己写一个strcmp函数(考察指针传参)
- P279_1017 写一函数,实现两个字符串的比较,即自己写一个strcmp函数
- 编一个程序,将两个字符串s1和s2比较,返回差值,即实现strcmp函数功能