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; }