1、strcpy(s1,s2);复制s2到s1中;
char *my_strcpy(char *dst,const char *src)
{
assert(dst != NULL);
assert(src != NULL);
char *ret = dst;
while((* dst++ = * src++) != '\0')
;
return ret;
}
上述的while执行过程:
- the contents of t (
*dst
) are copied to s (*src
), one character. src
anddst
are both incremented (++
).- the assignment (copy) returns the character that was copied (to the
while
). - the
while
continues until that character is zero (end of string inC
).
需要注意的是:
strcpy 会拷贝'\0',还有要注意:[4]
-
源指针所指的字符串内容是不能修改的,因此应该声明为 const 类型。
-
要判断源指针和目的指针为空的情况,思维要严谨,这里使用
assert
。 -
要用一个临时变量保存目的串的首地址,最后返回这个首地址。
-
函数返回 char* 的目的是为了支持链式表达式,即strcpy可以作为其他函数的实参。
等价于如下的代码:
while (*t) {
*s = *t;
s++;
t++;
}
*s = *t;
在C++中正确运行的效果:
#include <iostream>
using namespace std;
//#include<stdio.h>
#include<assert.h>
#define N 50
char *my_strcpy(char *dest, const char *src)
{
//返回值保存
char *p = dest;//检查入参,使程序健壮
assert(dest != NULL || src != NULL);//注意越界
while ((*dest++ = *src++) != '\0');
return p; //返回字符指针,使函数可以用于链式表达式,增强可用性
}
int main()
{
char str1[N];
char *str2 = "Everything is well.";
printf("%s\n", my_strcpy(str1, str2));
printf("%s\n", str1);
printf("%s\n", str2);
//system("pause");
//return 0;
}
运行结果:
Everything is well.
Everything is well.
Everything is well.
参考:
[1]https://blog.csdn.net/u014744118/article/details/48996653
[2] https://blog.csdn.net/Gpengtao/article/details/7464061
[3] https://stackoverflow.com/questions/810129/how-does-whiles-t-copy-a-string
[4] https://blog.csdn.net/lisonglisonglisong/article/details/44278013
2、strcat(s1,s2)
连接字符串s2到字符串s1的末尾
#include <assert.h>
#include <stdio.h>
char* strcat(char* des, const char* src) // const表明为输入参数
{
assert((des!=NULL) && (src!=NULL));
char* address = des;
while(*des != '\0') // 移动到字符串末尾
++des;
while(*des++ = *src++)
;
return address;
}
需要注意的是:des 和 src 所指内存区域不可以重叠且 des 必须有足够的空间来容纳 src 的字符串
在C++中运行的结果:
#include <iostream>
using namespace std;
#include <assert.h>
#include <stdio.h>
#define N 50
char* mystrcat(char* des, const char* src) // const表明为输入参数
{
assert((des!=NULL) && (src!=NULL));
char* address = des;
while(*des != '\0') // 移动到字符串末尾
++des;
while(*des++ = *src++)
;
return address;
}
int main()
{
char str1[N]="hh";//注意这里改为指针出错
char *str2 = "Everything is well.";
printf("%s\n", mystrcat(str1, str2));
printf("%s\n", str1);
printf("%s\n", str2);
//system("pause");
//return 0;
}
结果:
hhEverything is well.
hhEverything is well.
Everything is well.
参考:
[4] https://blog.csdn.net/lisonglisonglisong/article/details/44278013
3、strlen(s1)
返回字符串s1的长度
#include <assert.h>
#include <stdio.h>
int strlen(const char* str)
{
assert(str != NULL);
int len = 0;
while((*str++) != '\0')
++len;
return len;
}
注意:while循环的过程和第一种情况类似 先*str 然后再执行str++
C++ 中运行的结果:
#include <iostream>
using namespace std;
#include <assert.h>
#include <stdio.h>
int mystrlen(const char* str)
{
assert(str != NULL);
int len = 0;
while((*str++) != '\0')
++len;
return len;
}
int main()
{
char *str2 = "Ever .";
printf("%s\n", str2);
printf("strlen(str1)=%d, sizeof(str1)=%d\n", mystrlen(str2), sizeof(str2));
//system("pause");
//return 0;
}
运行结果:
Ever .
strlen(str1)=6, sizeof(str1)=8
4、strcmp(s1,s2)
s1=s2时 返回0
s1<s2时返回值小于0
s1>s2时返回值大于0
注意它们比较的是:ASCII值大小相比较, 两个字符比较,直到出现不同的字符或遇'\0'为止,也就是相等的情况是两个字符串的所有字符全部相等。
int mystrcmp(const char *str1, const char *str2)
{
int ret=0;
while( !(ret = *(unsigned char*)str1 - *(unsigned char*)str2 ) && *str1 )
{
str1++;
str2++;
}
if(ret < 0)
return -1;
else if(ret > 0)
return 1;
return 0;
}
C++中的实现:
#include <iostream>
using namespace std;
#include <assert.h>
#include <stdio.h>
int mystrcmp(const char *str1, const char *str2)
{
int ret=0;
while( !(ret = *(unsigned char*)str1 - *(unsigned char*)str2 ) && *str1 )
{
str1++;
str2++;
}
if(ret < 0)
return -1;
else if(ret > 0)
return 1;
return 0;
}
int main()
{
char *str1 = "Ever .";
char *str2 = "Aver .";
//char str1[] = "abcdf";
//char str2[] = "abcdw";
printf("%s\n", str2);
printf("%d\n",mystrcmp(str1, str2));
//system("pause");
//return 0;
}
运行结果:
Aver .
1
【1】https://blog.csdn.net/lina_acm/article/details/51910119 值得参考的博客(写的不错):
5、strchr(s1,ch)
返回一个指针,指向字符ch首次出现在S1中的位置
C++中实现:
char *mystrchr(const char *s,int ch)
{
assert(s!=NULL);
while(*s!='\0')
{
if(*s-ch==0)
return (char*)s;
s++;
}
return NULL;
}
需要注意的是:它是指针函数的实现。因为最后要返回地址和strcpy类似(区分前面的)。
#include <iostream>
using namespace std;
#include <assert.h>
#include <stdio.h>
char *mystrchr(const char *s,int ch)
{
assert(s!=NULL);
while(*s!='\0')
{
if(*s-ch==0)
return (char*)s;
s++;
}
return NULL;
}
int main()
{
char *str1 = "AEer .";
//char str1[] = "AEer .";
char *p ;
p=mystrchr(str1,'e');
if(p!=NULL)
{
cout<<"Findout!"<<endl;
cout<<p<<endl;
}
else
{
cout<<"Not Find!"<<endl;
}
//system("pause");
//return 0;
}
运行结果:
Findout!
er .
需要注意的是它返回的是首次出现的字符及后面的字符串。
区分指针函数和函数指针的区别
int *f(int i, int j);
int (*p)(int i, int j);
前者是返回值是指针的函数;后者是一个指向函数的指针。
参考:【1】https://blog.csdn.net/str999_cn/article/details/78591369
6、strstr(s1,s2)
返回一个指针,指向字符串s1中字符串s2出现的位置
类似KMP算法(朴素的)
char *mystrstr(const char *s1, const char *s2)
{
int n;
if (*s2)
{
while (*s1)
{
for (n = 0; *(s1 + n) == *(s2 + n); n ++)
{
if (!*(s2 + n + 1))
return (char *)s1;
}
s1++;
}
return NULL;
}
else
return (char *)s1;
}
C++中运行的实例:
#include <iostream>
using namespace std;
#include <assert.h>
#include <stdio.h>
char *mystrstr(const char *s1, const char *s2)
{
int n;
if (*s2)
{
while (*s1)
{
for (n = 0; *(s1 + n) == *(s2 + n); n ++)
{
if (!*(s2 + n + 1))
return (char *)s1;
}
s1++;
}
return NULL;
}
else
return (char *)s1;
}
int main()
{
char str1[] = "Abcabdabc .";
char str2[] = "abc";
//char *str1 = "Abcabdabc .";//可以为指针形式
//char *str2= "abc";
char *p ;
p=mystrstr(str1,str2);
if(p!=NULL)
{
cout<<"Findout!"<<endl;
cout<<p<<endl;
}
else
{
cout<<"Not Find!"<<endl;
}
//system("pause");
//return 0;
}
运行 结果:
Findout!
abc .注意的是选择指针的方式赋值字符串出错(类似第一种情况strcat)原因是? 注释没加好导致