strcpy, strcpy_s
来自cppreference.com
定义于头文件 <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
的错误值不暴露行将发生的缓冲区溢出。
- 同所有边界检查函数,
strcpy_s
仅若实现定义了 __STDC_LIB_EXT1__ ,且用户在包含<string.h>
前定义 __STDC_WANT_LIB_EXT1__ 为整数常量 1 才保证可用。
参数
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 <string.h> #include <stdio.h> #include <stdlib.h> int main(void) { char *src = "Take the test."; // src[0] = 'M' ; // 这会是未定义行为 char dst[strlen(src) + 1]; // +1 以适应空终止符 strcpy(dst, src); dst[0] = 'M'; // OK 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
引用
- C11 standard (ISO/IEC 9899:2011):
- 7.24.2.3 The strcpy function (p: 363)
- K.3.7.1.3 The strcpy_s function (p: 615-616)
- C99 standard (ISO/IEC 9899:1999):
- 7.21.2.3 The strcpy function (p: 326)
- C89/C90 standard (ISO/IEC 9899:1990):
- 4.11.2.3 The strcpy function
参阅
(C11) |
从一个字符串复制一定数量的字符到另一个 (函数) |
(C11) |
将一个缓冲区复制到另一个 (函数) |
(C95)(C11) |
将一个宽字符串复制给另一个 (函数) |
(动态内存 TR) |
分配字符串的副本 (函数) |