【C语言】strcpy()函数(字符串拷贝函数详解)

简介: 【C语言】strcpy()函数(字符串拷贝函数详解)

一.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语言字符串库函数思维导图:


相关文章
|
21天前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
56 24
|
17天前
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
52 16
|
17天前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
28 3
|
17天前
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
14 2
|
21天前
|
存储 编译器 C语言
【C语言程序设计——函数】回文数判定(头歌实践教学平台习题)【合集】
算术运算于 C 语言仿若精密 “齿轮组”,驱动着数值处理流程。编写函数求区间[100,500]中所有的回文数,要求每行打印10个数。根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码。如果操作数是浮点数,在 C 语言中是不允许直接进行。的结果是 -1,因为 -7 除以 3 商为 -2,余数为 -1;注意:每一个数据输出格式为 printf("%4d", i);的结果是 1,因为 7 除以 -3 商为 -2,余数为 1。取余运算要求两个操作数必须是整数类型,包括。开始你的任务吧,祝你成功!
46 1
|
8月前
|
存储 编译器 C语言
在C语言中的数组和字符串
在C语言中的数组和字符串
|
4月前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
138 8
|
6月前
|
安全 C语言
C语言8 数组与字符串
C语言8 数组与字符串
47 0
|
存储 机器学习/深度学习 Linux
【C语言】语言篇——数组和字符串
【C语言】语言篇——数组和字符串
55 0
|
存储 C语言
C语言之指针(指针数组以及指针的指针和字符串)
C语言之指针(指针数组以及指针的指针和字符串)
112 0

热门文章

最新文章