【C/C++】C语言复制字符串及复制函数汇总(strcpy()/memcpy()/strncpy()/memmove())

article/2025/9/30 6:11:03

目录:

  • strcpy()
    • 举例:
  • memcpy()
    • 举例:
  • strncpy()
    • 举例:
  • memmove()
    • 举例:

我们首先来考虑一个简单的问题,我们定义了一个字符串,然后想要复制这个字符串,在C语言中,我们可以for循环指针实现,假如我们用指针来操作

#include <stdio.h>char  str1[20]= "Zxiaoxuan";
char  str2[20];
char * pts1 = str1 ;
char * pts2 = str2;int main () {pts2=pts1;return  0;
}

这样pts2只是复制字符串str1的地址,而不是复制整个字符串。

 

那么如何进行整个字符串的复制呢

  1. 我们可以采用数组的方式来进行
#include<stdio.h>void copy_string(char str1[],char str2[]) {int i = 0;while(str2[i] != '\0') {str1[i] = str2[i];i++;}str1[i] = '\0';
}int main() { char a[100]="zxiaoxuan"; char b[100]=" ";copy_string(b,a);printf("%s\n",b);return 0;
}

输出:
在这里插入图片描述
2. 可以采用指针的方式来进行

#include<stdio.h>void copy_string(char *p1,char *p2) {while(*p2 != '\0') {*p1 = *p2;*p1++;*p2++;}*p1 = '\0';
}
int main() {char a[100]="zxiaoxuan";char b[100]=" ";copy_string(b,a);printf("%s\n",b);return 0;
}

输出:
在这里插入图片描述

除了上面两种,C语言有没有内置的函数来进行拷贝复制呢,当然是有的,下面我们来逐一介绍。

strcpy()

使用头文件:#include <string.h>

定义:char *strcpy(char *dest, const char *src);

参数:

destinin:目标字符数组;
source:源字符数组;

函数说明strcpy()会将参数src 字符串拷贝至参数dest 所指的地址。 用于对字符串进行复制,识别到字符串的结束符号‘\0’自动停止

返回值:返回参数dest 的字符串起始地址。

注意:

  • 参数 dest 的内存空间要足够大,否则拷贝可能会造成缓冲溢出。
  • strcpy() 在复制结束后会添加结束符\0,这点和strncpy()不同

strcpy()的参数是两个字符串指针,其中 *src源字符串可以是指针,数组名,或者字符串常量,但是*dest目标字符串必须位一个确定的数据对象(字符数组),而且应该已经开辟好了存储空间(已经做好初始化)

举例:

#include <stdio.h>
#include <string.h>
int main ()
{char  str1[]= "Zxiaoxuan";char  str2[20];char  str3[20];strcpy  (str2,str1);strcpy  (str3, "copy successful");printf  ( "str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);return  0;
}

输出:

在这里插入图片描述

memcpy()

使用头文件:C语言:#include <string.h> C++:#include<cstring>

定义:void memcpy(void *dest, const void *src, size_t n);

参数:

destinin:目标地址;
source:源地址;
n:复制的字节长度。

函数说明memcpy()复制 src 所指的内存数据的 n 个字节到 dest所指的内存地址上。也就是从源地址复制n 个字节到目标地址

第一个和第二个指针都是void型且第二个指针不能被修改,第三个参数是需要拷贝的内存长度按字节记。

返回值:返回指向 dest 的指针。返回的指针类型是void。

注意:

  • memcpy()并不限制被复制的数据类型,只是逐字节地进行复制,任何数据类型都可以进行复制,例如字符数组、整型、结构体、类等

  • memcpy() 会完整的复制 num个字节,不会遇到‘\0’而结束,这点与 strcpy() 不同

  • dest 和 src所指的内存空间地址不能重叠

  • 参数 dest 的内存空间要足够大,起码要大于等于 num个字节

  • 通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

举例:

#include  <string.h>
#include  <stdio.h>
#include  <stdlib.h>#define N (20)int main() {char *p1 = "zxiaoxuan";char *p2 = (char *)malloc(sizeof(char) * N);memcpy(p2, p1, N);printf("p2 = %s\n", p2);system("pause");return 0;
}

在这里插入图片描述

strncpy()

使用头文件:#include <string.h>

定义:char *strncpy(char *dest, const char *src, size_t len);

参数:

destinin:目标字符数组;
source:源字符数组;
len:复制的字符串长度。

函数说明strncpy()复制字符串 src 的前 len 个字节到 dest所指的内存地址上。

返回值:返回字符串dest

注意:

  • strncpy()在复制结束后不会向dest结尾添加’\0’结束符 这个是很重要的一个点,要记住
  • 如果source(源字符数组)的长度>复制的字符串数len,则只复制source(源字符数组)的前len个字符,不会自动添加结束符\0
  • 如果source(源字符数组)的长度<复制的字符串数len,则以NULL填充dest(目标字符数组),直到复制完n个字节
  • 参数 dest 的内存空间要足够大,起码要大于等于 num个字节
  • 在使用strncpy()的时候,拷贝长度最好为strlen(src)+1,以保证最后的结束符\0也能被复制

举例:

#include <stdio.h>
#include <string.h>int main () {char str1[]= "Z Xiao Xuan";char str2[40];char str3[40];/* 拷贝到缓冲区: */strncpy ( str2, str1, sizeof(str1)+1); //拷贝长度为 str1+1,将结束符\0也进行拷贝/* 拷贝 5 个字符: */strncpy ( str3, str2, 5 );str3[5] = '\0';   /* 手动加上终止符 */puts (str1);puts (str2);puts (str3);system("pause");return 0;
}

在这里插入图片描述

memmove()

使用头文件:#include <string.h>

定义:void *memmove( void* dest, const void* src, size_t count );

参数:

destinin:目标地址;
source:源地址;
count:复制的字节长度。

函数说明memmove()复制 src 所指的内存数据的 n 个字节到 dest所指的内存地址上。也就是从源地址复制n 个字节到目标地址。如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。

缓冲区重叠这个需要讲解一下:

根据dest(目标字符数组)内存区域和src(源字符数组)内存区域可分为三种情况:

    1. src内存区域和dest内存区域完全不重叠

在这里插入图片描述

    1. src(源字符数组)内存区域和dest(目标字符数组)内存区域存在重叠 且dest所在区域在src所在区域前
      在这里插入图片描述
      如上图,dest(目标字符数组)src(源字符数组)存在三个字节的内存区域重叠

但是在复制的时候,先把src的前三个字节复制到了dest的前三个内存区域内,再继续复制到重叠区域时,就算被覆盖,也不会有数据错误 所以这样可以正常复制

    1. src(源字符数组)内存区域和dest(目标字符数组)内存区域存在重叠,且在dst所在区域在src所在区域后面
      在这里插入图片描述
      这时候如果使用memcpy()进行复制,会把三个重叠内存字节覆盖为src的前三个字节内容,导致复制到重叠部分的时候出现错误

如果使用memmove(),会先将src(源字符数组)中的内容复制到缓冲区,然后再复制到dest(目标字符数组)中去,有效的避免了数据重叠。

举例:

下面举一个例子:

首先定义一个字符串str:memmove can be very useful......

然后把字符串的第15个字节~第25个字节的11个字节数据,复制到第20个字节~第30个字节中去

src(源字符数组)very useful
dest(目标字符数组)useful.....

重叠部分: 第20个字节~第25个字节

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main () {char str[] = "memmove can be very useful......";memmove (str+20,str+15,11);puts (str);system("pause");return 0;
}

先将11个字节的src(源字符数组)数据(very useful)内容复制到缓冲区中,再用缓冲区中的内容覆盖dest(目标字符数组)指向的内存(第20个字节~第30个字节),这样就避免了第20个字节~第25个字节的重叠

在这里插入图片描述
最后就变成了memmove can be very very useful.

在这里插入图片描述
请添加图片描述
请添加图片描述


http://chatgpt.dhexx.cn/article/VwWUQTbA.shtml

相关文章

C语言编写字符串拷贝(strcpy)函数详解以及assert函数

目录 一.strcpy函数 原型声明 功能 说明 代码及运行结果 二.自己编写strcpy函数 代码一及运行结果 代码二&#xff08;改进&#xff09;及运行结果 代码三&#xff08;进一步改进&#xff09;及assert函数 在这里解释一下什么是asser函数&#xff08;断言函数&#xff…

程序员一般通过什么平台接单

今天给大家介绍几个程序员可以接私活的平台。在外人眼中,程序员敲几行代码就能拿到不错的薪水,理所应当需要掌握与计算机方面相关的技术;私活没有那么好做,但是可以作为一个额外的收入渠道,或者想要找项目练手的程序员,都乐意利用自己的业余时间接私活。 1、程序员客栈 …

福利:总结10个Python赚钱的接单平台!兼职月入5000+

如果说当下什么编程语言最靠谱或者比较适合搞副业&#xff1f; 答案肯定100%是&#xff1a;Python Python是所有语法中最简单易上手的语言&#xff0c;不需要特别的的英语词汇量&#xff0c;逻辑思维也不需要很差就能上手。而且学会了之后就能编写代码爬取各种数据&#xff0c…

大一学生靠爬虫接单月入上万?这些接私活的外包平台分享给你!让你外包接到手软!

概叙 今天听一个同事说起他弟弟&#xff0c;同事他暑假教了两个月的python爬虫&#xff0c;也告诉他怎么接外包赚钱&#xff0c;本意是想他自己能在校给自己赚点生活费&#xff0c;不曾想到一月居然能赚这么多&#xff01;毕竟有了技术的话&#xff0c;除了工作上的&#xff0c…

程序员怎么接单赚外快,去这6个平台就可以了!

前言 说起程序员接外包的网站&#xff0c;你在网上一搜发现数不胜数&#xff0c;但真正有用的却很少。然后你想快速的找到几个靠谱的网站&#xff0c;去看了看接外包的攻略&#xff0c;你会发现排雷的又数不胜数。一时间你还真不知道要选哪一个。 接下来小编就为大家推荐几个…

福利:总结几个Python赚钱的接单平台,兼职月入5000+

如果说当下什么编程语言最靠谱或者比较适合搞副业&#xff1f; 答案肯定100%是&#xff1a;Python Python是所有语法中最简单易上手的语言&#xff0c;不需要特别的的英语词汇量&#xff0c;逻辑思维也不需要很差就能上手。而且学会了之后就能编写代码爬取各种数据&#xff0…

基于安卓的接的快接单平台/基于Android的快的接单平台

【摘要】 随着互联网的趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己的信息推广出去&#xff0c;最好方式就是建立自己的平台信息&#xff0c;并对其进行管理&#xff0c;随着现在智能手机的普及&#xff0c;人们对于智能手机里面的应用接的快接单平台也在不断的使用…

程序员的接单外卖平台

今天王同学给大家安利一款非常实用并且能接单的一款非常好的平台—— 独自开 独自开的功能非常之多 简直不要太香~ 集成第三方数学接口&#xff0c;形成标准化解决方案&#xff0c;提供开发者调用 支付分账功能电子签单功能税务接口硬件接口 独自开的开发功能简直不要太多~ 如…

效果图制作接单平台有哪些?

对于制图师来说&#xff0c;单子就是生命&#xff0c;就是白花花的票子&#xff0c;单子越多&#xff0c;票子越多。一般来说找单子不会是制图师来找&#xff0c;都是公司的商务拉来单子&#xff0c;制图师们只管出活&#xff0c;但如果想要更高的收入&#xff0c;想跳过层层转…

程序员接私活,接单平台

面向国内企业接单&#xff0c;主要好处就是对英语沟通能力的要求没那么高&#xff0c;不过客户屁事多&#xff0c;不懂装懂&#xff0c;需求来回改&#xff0c;喜欢瞎 bb&#xff0c;回款周期长的问题也普遍存在。 因此&#xff0c;我个人觉得&#xff0c;面向国内市场接单&am…

Java程序员接单平台推荐

Java程序员接单已经不再是新鲜事&#xff0c;也有不少学Java的兄弟通过接单得到了不错的收入&#xff1b;生活在二三线的程序员老铁们&#xff0c;靠接单也可以对等一线城市的收入。具体该怎么做&#xff0c;且听我娓娓道来。 (干货满满&#xff0c;建议大家点赞收藏&#xff…

常用Java接单平台一览

不少主攻Java的程序员兄弟除了工作&#xff0c;还会在空闲时间选择接单来增加自己的收入&#xff1b;对于那些生活在二三线的程序员兄弟们&#xff0c;通过接单&#xff0c;来获得与一线城市对等的收入。具体该怎么做&#xff0c;且听我娓娓道来。接下来干货满满&#xff0c;先…

那些你必须要知道的程序员接单平台

作为程序员来说&#xff0c;我们进行的大多数都可以在网络上进行&#xff0c;所以对于接单来说是非常方便的&#xff0c;起码你不需要千里迢迢跑到另外一个城市去进行一份兼职。所以说在闲暇时间动动手指&#xff0c;接几个单子增加点业余收入&#xff0c;也丰富一下自己的经验…

盘点六大程序员接单网站,务必收藏!

程序员接单不是啥新鲜事儿&#xff0c;不少程序员在工作之余会找一点单子来做&#xff0c;进而在二三线城市就拿到对标一线城市的薪资。 有的程序员会上论坛和一些接单群去找单子做&#xff0c;但是一般来说这种的工资会比较低&#xff0c;而且由于没有第三方的保障&#xff0c…

接单平台强烈推荐汇总

&#xff08;1&#xff09;程序员客栈 https://www.proginn.com/ &#xff08;10&#xff09;码市 https://codemart.com/ &#xff08;11&#xff09;猪八戒网 https://luoyang.zbj.com/ &#xff08;100&#xff09;开源众包 https://zb.oschina.net/ &#xff08;101&am…

服务器管理工具

文章目录 终端模拟&#xff08;Xshell 6&#xff09;安装配置 服务器文件传输&#xff08;WinSCP&#xff09;安装配置 终端模拟&#xff08;Xshell 6&#xff09; 安装 链接&#xff1a;https://pan.baidu.com/s/1aXPxtbpwxblfAwgdnQaZyQ 提取码&#xff1a;62qe 配置 新建…

世界上最好用的FTP服务器管理工具

1、服务器端&#xff1a;serv-u 2、客户端&#xff1a;FileZilla

云服务器管理

目录 使用云服务器的三大好处 什么是云服务器 一分钟快速定制ECS 三分钟便捷管理ECS 五分钟轻松运维ECS 运维场景一&#xff1a;使用ECS快照功能恢复误删的数据 运维场景二&#xff1a;性能监控、自动报警 云服务器使用的100种可能性 使用云服务器的三大好处 什么是云…

Mac系统服务器管理工具倾情推荐

文章目录 结论背景对比Mac下使用FinalShell登录效果&#xff1a;使用Iterm2效果 总结 读者朋友大家好&#xff0c;今天给Max系统推荐一款【服务器管理工具】-FinalShell 结论 登录服务器&#xff0c;Iterm2至少折腾1h&#xff0c;FinalShell几分钟。 背景 不同的OS&#xf…

【干货】系统管理员必备,服务器监控工具汇总

服务器监控工具对于IT基础架构性能、可视化和系统稳定至关重要。合适的工具能够帮助系统管理员面对服务器故障、应用缓慢、停机、内存泄露和配置依赖等挑战。 Nagios、Zabbix等工具是用于监控整个基础结构监控工具。使用它们&#xff0c;系统管理员可以监控几乎所有内容&#…