strcat, strcat_s
From cppreference.net
|
定义于头文件
<string.h>
|
||
| (1) | ||
|
char
*
strcat
(
char
*
dest,
const
char
*
src
)
;
|
(C99前) | |
|
char
*
strcat
(
char
*
restrict
dest,
const
char
*
restrict
src
)
;
|
(C99起) | |
|
errno_t strcat_s
(
char
*
restrict
dest, rsize_t destsz,
const
char
*
restrict
src
)
;
|
(2) | (C11起) |
1)
将
src
指向的以空字符结尾的字节字符串的副本追加到
dest
指向的以空字符结尾的字节字符串的末尾。
src[0]
字符将替换
dest
末尾的空终止符。生成的字节字符串以空字符结尾。
若目标数组的大小不足以容纳
src
和
dest
的内容及终止空字符,则行为未定义。若字符串存在重叠,则行为未定义。若
dest
或
src
不是指向以空字符结尾的字节字符串的指针,则行为未定义。
2)
与
(1)
相同,区别在于它可能用未指定的值覆盖目标数组的剩余部分(从最后写入的字符到
destsz
),并且在运行时检测到以下错误时会调用当前安装的
约束处理函数
:
-
-
src或dest是空指针 -
destsz为零或大于 RSIZE_MAX -
在
dest的前destsz个字节中没有空终止符 -
会发生截断(
dest末尾的可用空间无法容纳src的所有字符,包括空终止符) - 源字符串和目标字符串会发生重叠
-
若
dest
所指向的字符数组大小 <
strlen
(
dest
)
+
strlen
(
src
)
+
1
<=
destsz
,则行为未定义;换言之,错误的
destsz
值不会暴露即将发生的缓冲区溢出。
-
与所有边界检查函数一样,仅当实现定义了
__STDC_LIB_EXT1__
且用户在包含
<string.h>
前将
__STDC_WANT_LIB_EXT1__
定义为整型常量
1
时,才保证
strcat_s可用。
目录 |
参数
| dest | - | 指向要追加内容的以空字符结尾的字节字符串的指针 |
| src | - | 指向要复制的以空字符结尾的字节字符串的指针 |
| destsz | - | 最大写入字符数,通常是目标缓冲区的大小 |
返回值
1)
返回
dest
的副本
2)
成功时返回零,错误时返回非零值。此外,在发生错误时,将零写入
dest
[
0
]
(除非
dest
是空指针,或
destsz
为零或大于
RSIZE_MAX
)。
注释
由于
strcat
在每次调用时都需要定位到
dest
的末尾,因此使用
strcat
将多个字符串连接成一个字符串的效率较低。
strcat_s
允许为提升效率而覆盖目标数组中从最后写入字符到
destsz
的范围:它可能以多字节块形式复制数据,随后再检测空字节。
函数
strcat_s
与
BSD 函数
strlcat
类似,不同之处在于
-
strlcat会截断源字符串以适配目标缓冲区 -
strlcat不会执行strcat_s所具备的所有运行时检查 -
strlcat在调用失败时不会通过将目标字符串设为空字符串或调用处理程序来显式提示错误
尽管
strcat_s
因潜在安全风险禁止截断字符串,但可以通过使用边界检查的
strncat_s
来实现字符串截断。
示例
运行此代码
#define __STDC_WANT_LIB_EXT1__ 1 #include <string.h> #include <stdio.h> #include <stdlib.h> int main(void) { char str[50] = "Hello "; char str2[50] = "World!"; strcat(str, str2); strcat(str, " ..."); strcat(str, " Goodbye World!"); puts(str); #ifdef __STDC_LIB_EXT1__ set_constraint_handler_s(ignore_handler_s); int r = strcat_s(str, sizeof str, " ... "); printf("str = \"%s\", r = %d\n", str, r); r = strcat_s(str, sizeof str, " and this is too much"); printf("str = \"%s\", r = %d\n", str, r); #endif }
可能的输出:
Hello World! ... Goodbye World! str = "Hello World! ... Goodbye World! ... ", r = 0 str = "", r = 22
参考文献
- C11 标准 (ISO/IEC 9899:2011):
-
- 7.24.3.1 strcat 函数 (第 364 页)
-
- K.3.7.2.1 strcat_s 函数 (第 617-618 页)
- C99 标准 (ISO/IEC 9899:1999):
-
- 7.21.3.1 strcat 函数 (第 327 页)
- C89/C90 标准 (ISO/IEC 9899:1990):
-
- 4.11.3.1 strcat 函数
参考
|
(C11)
|
连接两个字符串的指定数量字符
(函数) |
|
(C11)
|
将一个字符串复制到另一个字符串
(函数) |
|
(C23)
|
将一个缓冲区复制到另一个缓冲区,遇到指定分隔符后停止
(函数) |
|
C++ 文档
for
strcat
|
|