strcpy 函数简介
strcpy (string copy) 的作用是将源字符串(包括结尾的 \0)完整地拷贝到目标字符数组(缓冲区)中。

函数原型:
#include <string.h> char *strcpy(char *dest, const char *src);
参数:
dest: 目标字符数组(或指向字符数组的指针),必须有足够的空间来容纳源字符串,否则会导致缓冲区溢出,这是非常危险的。src: 源字符串(或指向字符串的指针)。const关键字表示这个字符串不会被strcpy修改。
返回值:
- 成功时,返回指向目标字符串
dest的指针。
工作原理
strcpy 的工作流程非常简单:

- 从
src指向的内存地址开始读取字符。 - 将读取的字符依次写入
dest指向的内存地址。 - 当读取到
src中的空字符\0时,拷贝停止。 \0也会被拷贝到dest中,作为新字符串的结束标志。
简单图示:
src: [ 'H' | 'e' | 'l' | 'l' | 'o' | '\0' | ... ]
^
|
dest: [ ? | ? | ? | ? | ? | ? | ... ]
|
v
After strcpy:
dest: [ 'H' | 'e' | 'l' | 'l' | 'o' | '\0' | ... ]
代码示例
下面是一个 strcpy 的基本使用示例。
#include <stdio.h>
#include <string.h> // 必须包含这个头文件才能使用 strcpy
int main() {
// 1. 定义目标数组,必须足够大
// 源字符串 "Hello, World!" 有 13 个字符,加上 '\0' 需要 14 个字节
char destination[20];
const char *source = "Hello, World!";
// 2. 使用 strcpy 进行拷贝
// 将 source 的内容拷贝到 destination
strcpy(destination, source);
// 3. 打印结果
printf("源字符串: %s\n", source);
printf("目标字符串: %s\n", destination);
return 0;
}
输出:
源字符串: Hello, World!
目标字符串: Hello, World!
重要注意事项(非常关键!)
1 缓冲区溢出
这是 strcpy 最常见也是最危险的陷阱。你必须确保目标缓冲区 dest 的大小足够容纳源字符串 src(包括 \0)。

错误示例:
#include <stdio.h>
#include <string.h>
int main() {
// 目标缓冲区太小,只有 5 个字节
char destination[5];
const char *source = "This is a very long string!";
// 危险!source 的长度超过了 destination 的大小
// 这会导致缓冲区溢出,可能会覆盖 destination 之后的内存数据
// 引发程序崩溃或安全漏洞
strcpy(destination, source);
printf("拷贝后的内容: %s\n", destination); // 输出是不可预测的
return 0;
}
后果:
- 程序崩溃(段错误)。
- 覆盖了其他重要变量,导致程序逻辑错误。
- 在服务器或网络应用中,这可能被利用来执行恶意代码,这是非常严重的安全漏洞。
2 不检查源指针
src 是一个空指针(NULL),程序会尝试从地址 0 读取数据,这几乎必然导致程序崩溃。
错误示例:
#include <stdio.h>
#include <string.h>
int main() {
char destination[50];
const char *source = NULL; // 源指针是 NULL
strcpy(destination, source); // 崩溃!
return 0;
}
更安全的替代方案
由于 strcpy 存在缓冲区溢出的风险,现代 C 编程中通常会使用更安全的替代函数。
1 strncpy
strncpy 可以指定最多拷贝的字符数,从而避免溢出。
函数原型:
char *strncpy(char *dest, const char *src, size_t n);
n: 最多拷贝n个字符。
工作原理:
strlen(src) < n,则src的内容(包括\0)被完整拷贝到dest,剩余的空间用\0填充。strlen(src) >= n,则只拷贝n个字符,dest不会被自动添加\0,这会导致dest不是一个合法的 C 字符串,后续使用printf等函数可能会越界读取。
安全使用 strncpy 的示例:
#include <stdio.h>
#include <string.h>
int main() {
char destination[10];
const char *source = "Hello";
// 最多拷贝 9 个字符,为 '\0' 预留一个位置
// 注意:strncpy 不会自动添加 '\0',所以我们必须手动处理
strncpy(destination, source, sizeof(destination) - 1);
// 手动添加字符串结束符,确保 dest 是合法的 C 字符串
destination[sizeof(destination) - 1] = '\0';
printf("安全拷贝后的内容: %s\n", destination); // 输出: Hello
return 0;
}
2 snprintf (推荐)
函数原型: 当用于字符串拷贝时,可以这样用: 优点: 推荐示例: 核心建议:
除非你 100% 确定源字符串的长度永远不会超过目标缓冲区,否则请优先使用 snprintf 是最现代、最安全的字符串拷贝函数之一,它会根据目标缓冲区的大小自动进行截断,并确保字符串总是以 \0
int snprintf(char *str, size_t size, const char *format, ...);
snprintf(dest, sizeof(dest), "%s", src);
dest 写入 size - 1 个字符,并自动在末尾添加 \0。src 多长,dest 都会是一个合法的、以 \0 结尾的字符串。format 字符串的长度(不包括 \0),可以利用这个返回值来判断字符串是否被截断。#include <stdio.h>
#include <string.h>
int main() {
char destination[10];
const char *source = "This is a very long string!";
// 使用 snprintf 安全拷贝
// 最多向 destination 写入 9 个字符,并自动添加 '\0'
snprintf(destination, sizeof(destination), "%s", source);
printf("安全拷贝后的内容: %s\n", destination); // 输出: This is a
printf("destination 的实际长度: %zu\n", strlen(destination)); // 输出: 9
return 0;
}
函数
安全性
描述
推荐度
strcpy不安全
简单,但极易导致缓冲区溢出。
⭐ (仅用于受信任的、明确知道长度足够的情况)
strncpy相对安全
可指定长度,但需要手动添加
\0,否则可能导致字符串未正确终止。⭐⭐⭐ (需要小心使用)
snprintf非常安全
自动处理长度,自动添加
\0,是现代 C 语言的黄金标准。⭐⭐⭐⭐⭐ (强烈推荐)
snprintf 来进行字符串拷贝,它能从根本上避免缓冲区溢出的问题,让你的程序更加健壮和安全。
