strcpy, strcpy_s
From cppreference.net
|
定义于头文件
<string.h>
|
||
| (1) | ||
|
char
*
strcpy
(
char
*
dest,
const
char
*
src
)
;
|
(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_MAX
- destsz 小于或等于 strnlen_s ( src, destsz ) ;换言之,将发生截断
- 源字符串与目标字符串存在重叠
若
dest
所指向的字符数组大小
<=
strnlen_s
(
src, destsz
)
<
destsz
,则行为未定义;换言之,
destsz
的错误取值可能导致缓冲区溢出。
-
与所有边界检查函数相同,仅当实现定义了
__STDC_LIB_EXT1__
且用户在包含
<string.h>
前将
__STDC_WANT_LIB_EXT1__
定义为整型常量
1
时,才保证
strcpy_s可用。
目录 |
参数
| 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
|
|