strcpy, strcpy_s
来自 zh.cppreference.net
| 定义于头文件 <string.h>
|
||
char* strcpy( char* dest, const char* src );
|
(1) | (C99前) |
char* strcpy( char* restrict dest, const char* restrict src );
|
(C99起) | |
errno_t strcpy_s( char* restrict dest, rsize_t destsz, const char* restrict src );
|
(2) | (C11起) |
1) 将由
src, 包括空终止字符, 复制到其第一个元素由dest。 行为未定义如果
dest 数组不够大。 行为未定义如果字符串重叠。 行为未定义如果 dest 不是指向字符数组的指针或 src 不是指向空终止字节字符串的指针。2) 同 (1)), 除了它可能会用未指定值覆盖目标数组的其余部分,并且以下错误在运行时被检测到并调用当前安装的 约束处理函数 函数:
src或dest是空指针destsz为零或大于RSIZE_MAXdestsz小于或等于strnlen_s(src, destsz); 换句话说,将发生截断- 源字符串和目标字符串之间将发生重叠
行为未定义如果由
dest <= strnlen_s(src, destsz) < destsz; 换句话说,错误值 destsz 不会暴露即将发生的缓冲区溢出。 与所有边界检查函数一样,
strcpy_s 仅保证在以下情况下可用:__STDC_LIB_EXT1__ 由实现定义,并且用户将 __STDC_WANT_LIB_EXT1__ 定义为整数常量 1 在包含 <string.h>。参数
| dest | - | 指向要写入的字符数组的指针 |
| src | - | 指向要复制的以空字符结尾的字节字符串的指针 |
| destsz | - | 要写入的最大字符数,通常是目标缓冲区的大小 |
返回值
1)
返回
dest
的副本
2)
成功时返回零,错误时返回非零值。此外,在发生错误时,会向
dest
[
0
]
写入零值(除非
dest
是空指针,或
destsz
为零,或大于
RSIZE_MAX
)。
注释
strcpy_s
被允许为提升效率而覆盖目标数组中从最后写入字符到
destsz
的范围:它可能以多字节块形式进行复制,随后再检查空字节。
函数
strcpy_s
与 BSD 函数
strlcpy
类似,不同之处在于
-
strlcpy会截断源字符串以适应目标缓冲区(存在安全风险) -
strlcpy不执行strcpy_s所具备的所有运行时检查 -
strlcpy在调用失败时不会通过将目标缓冲区设为空字符串或调用处理程序来明确提示失败
尽管
strcpy_s
因潜在安全风险禁止截断操作,但可以通过使用边界检查的
strncpy_s
来实现字符串截断。
示例
运行此代码
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { const char* src = "Take the test."; // src[0] = 'M' ; // 这将导致未定义行为 char dst[strlen(src) + 1]; // +1 用于容纳空终止符 strcpy(dst, src); dst[0] = 'M'; // 正确 printf("src = %s\ndst = %s\n", src, dst); #ifdef __STDC_LIB_EXT1__ set_constraint_handler_s(ignore_handler_s); int r = strcpy_s(dst, sizeof dst, src); printf("dst = \"%s\", r = %d\n", dst, r); r = strcpy_s(dst, sizeof dst, "Take even more tests."); printf("dst = \"%s\", r = %d\n", dst, r); #endif }
可能的输出:
src = Take the test. dst = Make the test. dst = "Take the test.", r = 0 dst = "", r = 22
参考文献
- C23 标准 (ISO/IEC 9899:2024):
-
- 7.24.2.3 strcpy 函数 (p: TBD)
-
- K.3.7.1.3 strcpy_s 函数 (p: TBD)
- C17 标准 (ISO/IEC 9899:2018):
-
- 7.24.2.3 strcpy 函数 (页码: 264-265)
-
- K.3.7.1.3 strcpy_s 函数 (页码: 447)
- C11 标准 (ISO/IEC 9899:2011):
-
- 7.24.2.3 strcpy 函数 (p: 363)
-
- K.3.7.1.3 strcpy_s 函数 (p: 615-616)
- C99标准(ISO/IEC 9899:1999):
-
- 7.21.2.3 strcpy函数(页码:326)
- C89/C90 标准 (ISO/IEC 9899:1990):
-
- 4.11.2.3 strcpy 函数
参阅
|
(C11)
|
将指定数量的字符从一个字符串复制到另一个字符串
(函数) |
|
(C11)
|
将一个缓冲区复制到另一个缓冲区
(函数) |
|
(C95)
(C11)
|
将一个宽字符串复制到另一个宽字符串
(函数) |
|
(dynamic memory TR)
|
分配字符串副本
(函数) |
|
C++ documentation
for
strcpy
|
|