C
编译器支持
语言
头文件
类型支持
程序实用工具
可变参数函数支持
错误处理
动态内存管理
字符串库
算法
数值
日期和时间实用工具
输入/输出支持
本地化支持
并发支持 (C11)
技术规范
符号索引
[编辑] 字符串库
空字符结尾的字节字符串
空字符结尾的多字节字符串
空字符结尾的宽字符串
[编辑] 空字符结尾的字节字符串
函数
字符操作
isalnum
isalpha
islower
isupper
isdigit
isxdigit
isblank(C99)
iscntrl
isgraph
isspace
isprint
ispunct
tolower
toupper
数值格式之间的转换
atoiatolatoll(C99)
atof
strtolstrtoll(C99)
strtoulstrtoull(C99)
strtoimaxstrtoumax(C99)(C99)
strtofstrtodstrtold(C99)(C99)
strfromfstrfromdstrfroml(C23)(C23)(C23)
字符串操作
strcpystrcpy_s(C11)
strncpystrncpy_s(C11)
strcatstrcat_s(C11)
strncatstrncat_s(C11)
strxfrm
strdup(C23)
strndup(C23)
字符串检查
strlenstrnlen_s(C11)
strcmp
strncmp
strcoll
strchr
strrchr
strspn
strcspn
strpbrk
strstr
strtokstrtok_s(C11)
内存操作
memchr
memcmp
memsetmemset_explicitmemset_s(C23)(C11)
memcpymemcpy_s(C11)
memmovememmove_s(C11)
memccpy(C23)
杂项
strerrorstrerror_sstrerrorlen_s(C11)(C11)
[编辑]
定义于头文件
(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__ 并且用户在包含
目录
1 参数
2 返回值
3 注释
4 示例
5 参考文献
6 参见
[编辑] 参数
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
#include
#include
int main(void)
{
const char* src = "Take the test.";
// src[0] = 'M' ; // this would be undefined behavior
char dst[strlen(src) + 1]; // +1 to accommodate for the null terminator
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 strcpy 函数 (p: TBD)
K.3.7.1.3 strcpy_s 函数 (p: TBD)
C17 标准 (ISO/IEC 9899:2018)
7.24.2.3 strcpy 函数 (p: 264-265)
K.3.7.1.3 strcpy_s 函数 (p: 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 函数 (p: 326)
C89/C90 标准 (ISO/IEC 9899:1990)
4.11.2.3 strcpy 函数
[编辑] 参见
strncpystrncpy_s(C11)
将一定数量的字符从一个字符串复制到另一个字符串 (函数) [编辑]
memcpymemcpy_s(C11)
将一个缓冲区复制到另一个缓冲区 (函数) [编辑]
wcscpywcscpy_s(C95)(C11)
将一个宽字符串复制到另一个宽字符串 (函数) [编辑]
strdup(动态内存 TR)
分配字符串的副本 (函数) [编辑]
C++ 文档 关于 strcpy