1、strcpy()
strcpy() 将源字符串 src 复制到目标字符串 dest 中,包括字符串的结尾 \0(null 字符)。但strcpy() 不会检查目标数组的大小,因此如果目标数组没有足够的空间来存放源字符串,它可能会导致缓冲区溢出,这是一种常见的安全漏洞。
#include <stdio.h>
#include <string.h>
int main() {
// 定义目标数组和源字符串
char dest[20];
const char *src = "Hello, World!";
// 使用 strcpy 将 src 复制到 dest
strcpy(dest, src);
// 输出 dest 字符串
printf("Copied string: %s\n", dest);
return 0;
}
2、strncpy()
strncpy() 将最多 n 个字符从源字符串 src 复制到目标字符串 dest。如果源字符串的长度小于 n,则会在目标字符串中填充多余的 \0 字符,直到复制了 n 个字符为止。但strncpy() 不一定会在目标字符串的末尾添加 \0,如果源字符串长度大于或等于 n,目标字符串不会以 \0 结尾,因此需要特别小心。
#include <stdio.h>
#include <string.h>
int main() {
char dest[20]; // 目标字符数组,大小为 20
const char *src = "Hello"; // 源字符串
// 使用 strncpy 复制最多 10 个字符
strncpy(dest, src, 10);
// 确保目标字符数组以 '\0' 结尾
dest[19] = '\0'; // 将最后一个字符设置为 '\0',防止未终止的字符串
// 打印目标字符数组
printf("Destination string: %s\n", dest);
return 0;
}
3、strcpy() 和 strncpy() 的区别
strcpy() 将一个字符串从源复制到目标,直到遇到字符串结束符 \0。如果目标数组的大小不够大,就会导致内存越界问题,造成潜在的安全漏洞。
strncpy() 将最多 n 个字符从源复制到目标。如果源字符串长度小于 n,则在目标字符串末尾添加空字符 \0;如果源字符串长度大于或等于 n,则目标字符串不会添加 \0,这可能会导致字符串没有正确结束。
strcpy() 的问题在于没有边界检查,容易导致缓冲区溢出,从而引发安全漏洞。strncpy() 提供了最大字符数的限制,从而降低了溢出风险,但仍然有其缺陷,比如没有自动添加 \0 结束符,可能需要额外的处理。
在实践中,使用 strncpy() 时应该小心,确保目标字符串正确结束,并且目标缓冲区足够大。
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest1[20];
char dest2[10];
// 使用 strcpy()
strcpy(dest1, src);
printf("dest1 after strcpy: %s\n", dest1); // 输出: Hello, World!
// 使用 strncpy()
strncpy(dest2, src, sizeof(dest2) - 1); // 保证 dest2 不会溢出
dest2[sizeof(dest2) - 1] = '\0'; // 确保字符串以 null 结尾
printf("dest2 after strncpy: %s\n", dest2); // 输出: Hello
return 0;
}