strcpy, strcpy_s
来自cppreference.com
<tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
| 在标头 <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_MAXdestsz小于或等于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 并进行截断字符串。
示例
运行此代码
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <string.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
引用
- C23 标准(ISO/IEC 9899:2024):
- 7.24.2.3 The strcpy function (第 TBD 页)
- K.3.7.1.3 The strcpy_s function (第 TBD 页)
- C17 标准(ISO/IEC 9899:2018):
- 7.24.2.3 The strcpy function (第 264-265 页)
- K.3.7.1.3 The strcpy_s function (第 447 页)
- C11 标准(ISO/IEC 9899:2011):
- 7.24.2.3 The strcpy function (第 363 页)
- K.3.7.1.3 The strcpy_s function (第 615-616 页)
- C99 标准(ISO/IEC 9899:1999):
- 7.21.2.3 The strcpy function (第 326 页)
- C89/C90 标准(ISO/IEC 9899:1990):
- 4.11.2.3 The strcpy function
参阅
(C11) |
从字符串复制一定数量的字符到另一个 (函数) |
(C11) |
复制缓冲区到另一个 (函数) |
(C95)(C11) |
复制宽字符串给另一个 (函数) |
(动态内存 TR) |
分配字符串的副本 (函数) |
strcpy 的 C++ 文档
| |