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
まで)を不定値で上書きする可能性があり、以下のエラーが実行時に検出され、現在設定されている
constraint handler
関数を呼び出す:
-
-
srcまたはdestがヌルポインタ -
destszがゼロまたは RSIZE_MAX より大きい -
destの先頭destszバイト内にナルターミネータがない -
切り捨てが発生する(
destの末尾の利用可能スペースがsrcのすべての文字(ナルターミネータを含む)を格納できない) - ソース文字列と宛先文字列がオーバーラップする
-
destが指す文字配列のサイズが
dest
<
strlen
(
dest
)
+
strlen
(
src
)
+
1
<=
destsz
の場合、動作は未定義です。つまり、誤ったdestszの値は差し迫ったバッファオーバーフローを露呈しません。
-
すべての境界チェック付き関数と同様に、
strcat_sは、実装によって __STDC_LIB_EXT1__ が定義されており、かつユーザーが <string.h> をインクルードする前に __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義している場合にのみ利用可能であることが保証されます。
目次 |
パラメータ
| dest | - | 追加先のヌル終端バイト文字列へのポインタ |
| src | - | コピー元のヌル終端バイト文字列へのポインタ |
| destsz | - | 書き込む最大文字数(通常は宛先バッファのサイズ) |
戻り値
1)
dest
のコピーを返す
2)
成功時はゼロを返し、エラー時は非ゼロを返します。また、エラー時には
dest
[
0
]
にゼロを書き込みます
(ただし
dest
がnullポインタの場合、または
destsz
がゼロまたは
RSIZE_MAX
より大きい場合は除く)。
注記
strcat
は各呼び出しで
dest
の終端を検索する必要があるため、
strcat
を使用して多数の文字列を1つに連結するのは非効率的です。
strcat_s
は効率を改善するために、書き込まれた最後の文字から
destsz
までの宛先配列を破壊することが許可されています:マルチバイトブロックでコピーした後、nullバイトをチェックする場合があります。
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関数 (p: 364)
-
- K.3.7.2.1 strcat_s関数 (p: 617-618)
- C99標準 (ISO/IEC 9899:1999):
-
- 7.21.3.1 strcat関数 (p: 327)
- C89/C90標準 (ISO/IEC 9899:1990):
-
- 4.11.3.1 strcat関数
関連項目
|
(C11)
|
二つの文字列の特定の文字数を連結する
(関数) |
|
(C11)
|
文字列を別の文字列にコピーする
(関数) |
|
(C23)
|
バッファを別のバッファにコピーし、指定された区切り文字の後で停止する
(関数) |
|
C++ドキュメント
for
strcat
|
|