一.strcpy()函数简介
我们先来看一下cplusplus.com - The C++ Resources Network网站上strcpy()函数的基本信息:
1.函数功能
可以看到,strcpy()函数的功能是:
将源头指向的C字符串复制到目标指向的数组中,包括结尾的'/0'字符,并在'\0'字符处停止拷贝.
2.函数参数
该函数一共有两个参数,分别是:
char * strcpy ( char * destination, const char * source );
1>.char * destination
第一个参数的类型是char*(字符型指针),它指向拷贝的目的地内存块的起始地址,它的作用是为函数提供目的地的地址,以便函数能够准确地将内容拷贝到目的地的地址空间.
2>.const char * source
第二个参数的类型是被const修饰(const修饰的指针,const在*左表示指针指向的内容不可修改,const在*右表示指针的指向不可修改)的char*(字符型指针),它指向拷贝信息的来源内存块的起始地址,它的作用是为函数提供拷贝源头的地址,以便函数能够准确找到拷贝的源头进行拷贝.
3.函数返回值
函数的返回值类型是char*(字符型指针),它的作用是在函数运行结束后返回拷贝后的目的地内存块的起始地址.
4.函数头文件
该函数包含在头文件<string.h>中.
二.strcpy()函数的具体使用
strcpy()函数的使用场景是:
当我们想将一个字符串的内容拷贝到另一个字符串中时,我们可以使用strcpy()函数来实现这一诉求.
1.使用strcpy()函数完成字符数组间的字符拷贝
如下,我们使用strcpy()函数将字符数组str1中的内容拷贝到str2数组中:
分别给strcpy()函数传入两个参数:
拷贝目的地址(即str2),拷贝来源地址(即str1).
#define _CRT_SECURE_NO_WARNINGS 1 /* strcpy example */ #include <stdio.h> #include <string.h> int main() { char str1[] = "Sample string"; char str2[40]={0}; printf("str1: %s\nstr2: %s\n", str1, str2); strcpy(str2, str1); printf("str1: %s\nstr2: %s\n", str1, str2); return 0; }
在vs2022编译器中运行查看结果:
可见strcpy()函数成功将str1中的内容拷贝到了str2中.
2.使用strcpy()函数完成字符数组与常量字符串间的拷贝
除了上述将字符串数组中的字符串拷贝到字符串数组中的操作,我们还可以让strcpy()函数将常量字符串中的字符串拷贝到字符数组中,如:
分别给strcpy()函数传入:
拷贝目的地址(即str1),拷贝来源地址(一个常量字符串).
/* strcpy example */ #include <stdio.h> #include <string.h> int main() { char str3[40] = {0}; printf("str3: %s\n", str3); strcpy(str3, "copy successful"); printf("str3: %s\n",str3); return 0; }
在vs2022编译器中运行查看结果:
可见strcpy()函数成功的将常量字符串中的内容拷贝到了str3中.
除了上面那种直接将常量字符串放在参数位置形式的传参方式,我们还可以通过传递创建的常量字符串指针的形式传参,如:
/* strcpy example */ #include <stdio.h> #include <string.h> int main() { char str3[40] = {0}; char* str4 = "copy successful";//创建一个常量字符串指针str4 printf("str3: %s\n", str3); strcpy(str3,str4); printf("str3: %s\n",str3); return 0; }
在vs2022编译器中运行查看结果:
可见strcpy()函数成功的将常量字符串str4中的内容拷贝到了str3中.
三.模拟实现strcpy()函数功能
🎏实现思路
1.函数参数及返回值设定逻辑
📌函数参数
char * destination
因为strcpy()函数要实现的是字符串的拷贝,所以在使用strcpy()函数时我们只需要确保其可以处理字符型指针即可,因此在这里我们需要将目的地的地址类型设置为字符型指针,以便函数后续可以处理字符类型的数据.
const char * source
将来源地址的类型设置为字符型指针的原因与目的地的原因相同,都是便于函数可以处理字符型的数据.
而给来源的地址指针加上const的原因是防止拷贝的过程中将来源的内容不慎修改,在*指针左侧加上const就可以使const修饰的指针指向的内容变成常量.
📌函数返回值
char*
函数返回值设置为char*的原因同目的地及来源地相同,都是便于函数可以在处理完字符类型的数据后可以返回目的地的地址.
2.函数功能实现
采用循环的方式将字符串内容逐一拷贝,直到拷贝完源头字符串的结束标志'\0'为止.
注意事项:
- 因为最后需要返回目的地的起始地址,因此拷贝前应当提点记录下目的地起始位置的指针.
- 因为无论源地址为NULL,还是目的地地址为NULL,在后续函数的运行过程中都会导致指针的越界访问,因此我们选择在函数一开始就加入assert断言,防止传入空指针情况的出现.
- 我们循环终止的条件是(源字符串不等于'\0'),这意味着当函数拷贝到'\0'字符时就会停止拷贝,结束运行,这会导致'\0'并没有被拷贝到目的地中,后续可能会导致出现一些Bug.因此我们应该在循环结束后再将'\0'也拷贝到目的地中,防止程序出现问题.
🎏代码编写
char* my_strcpy(char* destination,const char* source) { assert(source); assert(destination); char* ret = destination; //用来记录目的地地址,以便后续返回 while (*source != '\0') { *destination = *source; destination++; source++; } *destination = *source; //拷贝'\0' return ret; }
🎏运行测试
使用my_strcpy()函数将字符数组str1中的内容拷贝到str2数组中,以及使用my_strcpy()函数将常量字符串str4中的字符串拷贝到str3字符数组中:
vs2022中测试如下:
成功运行,最后我们测试一下函数遇到传参为NULL指针的情况:
可以看到,assert()成功抛出了异常,并终止了程序非法运行:
结语
希望这篇strcpy()函数的介绍到能对大家有所帮助,欢迎大佬们留言或私信与我交流.
学海漫浩浩,我亦苦作舟!大家一起学习,一起进步!
C语言字符串库函数思维导图: