strcat
我自己写的是这样:
char* _strcat(char *_Dest, const char *_Source)
{
assert((_Dest != NULL) && (_Source != NULL));
char* p= _Dest;
while(*p!='\0')
{
p++;
}
const char* temp = _Source;
while( *temp!='\0')
{
*p=*temp;
p++;
temp++;
}
return _Dest;
}
strcat
的源码如下:
char *strcat(char *des, const char *src)
{
assert((des!=NULL) && (src!=NULL));
char* address = des;
while(*des != '\0') // 移动到字符串末尾
++des;
while(*des++ = *src++) //dest的下一个字符用src的下一个字符赋值
;
return address;
}
必须加assert判断,src指向的字符添加到dest所指向的结尾处,覆盖原来的\0
,添加新的\0
。二者所指的内存区不可重叠,并且dest要有足够的内存容纳src字符串,但源码也没有对此判断,所以它是危险的。注意其中dest不能指向常量区。
这样用是错的,p1指向了常量字符串:
char *p1 = "123";
char *p2 = "ABC";
std::cout<<strcat(p1,p2)<<endl;
改变连接的起始点:
char p1[4]="123";
char p2[4]="ABC";
std::cout<<strcat(p1+2,p2)<<endl;
结果是3ABC
。
以’\0’作为连接的标志:
char p1[40]="123\0abc";
char p2[8]="ABC\0DEF";
std::cout<<strcat(p1,p2)<<endl;
结果是123ABC
。
strcpy
函数源码:
char* _strcpy(char *dst, const char *src)
{
assert((dst!=NULL)&&(src!=NULL));
char* p1 =dst;
const char* p2 = src;
while(*p1!='\0')
{
*p1 = *p2;
p1++;
p2++;
}
return dst;
}
函数不安全,src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
源指针所指的字符串内容是不能修改的,因此应该声明为 const 类型。与strcat
相比,没有先移动到dst末尾。注意复制src到\0
为止。
测试代码:
char s1[]="12345";
char s2[]="abc";
std::cout<<strcpy(s1,s2)<<endl; //abc
复制s2到s1时,以\0
为准。
strlen
我写的实现代码:
int _strlen(const char* s)
{
assert(s!=NULL);
char* p =s;
int n=0;
while(*p!='\0')
{
p++;
n++;
}
return n;
}
注意指针不能为NULL,不统计最后的’\0’
strcmp
两个字符串的大小不能用关系运算符判断,应该用strcmp(a,b)
,两个字符串相同时返回0,a>b返回一个正值,否则返回负值.
从左向右逐个比较a,b中的字符,根据二者的ASCII值确定结果,如果二者一直相同,但字符串a长度较小,那么结果为负。
我用的编译器对正负的处理是1和-1,有的是ASCII的差值。
我是这样实现的:
int _strcmp(const char *dst, const char *src)
{
assert((dst!=NULL)&&(src!=NULL));
const char* p1 = dst;
const char* p2 = src;
while(*p1!='\0' && *p2!='\0')
{
if(*p1 > *p2)
return 1;
else if(*p1 < *p2)
return -1;
p1++;
p2++;
}
if(*p1!='\0' && *p2=='\0')
return 1;
else if(*p1=='\0' && *p2!='\0')
return -1;
return 0;
}
一种源码是这样的:
int strcmp(const char *s1, const char *s2)
{
//两字符串相等的情况,如果两个字符串中所有的字符相等,则返回0
while (*s1 == *s2++) //两个字符相等
if (*s1++ == 0) //达到字符串末尾
return (0);
//不相等,则返回值为第一次不相等时的两字符之差
return (*(unsigned char *)s1 - *(unsigned char *)--s2);
}
以上几个函数中的src全要加const限定,strcmp的两个参数都要加const
参考: 博客