strcat, strcat_s
From cppreference.com
| ヘッダー <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` の末尾のヌル終端子を置き換えます。結果のバイト文字列はヌル終端されます。
`dest` 配列が `src` と `dest` の両方の内容および終端ヌル文字を格納するのに十分な大きさでない場合、動作は未定義です。文字列が重複している場合、動作は未定義です。`dest` または `src` のどちらかがヌル終端バイト文字列へのポインタでない場合、動作は未定義です。
2) (1) と同じですが、宛先配列の残りの部分(最後に書き込まれた文字から `destsz` まで)を未指定の値で上書きする可能性があり、実行時に以下のエラーが検出され、現在インストールされている 制約ハンドラ 関数が呼び出されます。
- `src` または `dest` がヌルポインタである場合
- `destsz` がゼロまたは `RSIZE_MAX` より大きい
- `dest` の最初の `destsz` バイトにヌル終端子がない
- 切り捨てが発生する(`dest` の末尾の利用可能なスペースに、`src` のすべての文字(ヌル終端子を含む)が収まらない)
- ソース文字列と宛先文字列の間に重複が発生する場合
`dest` によって指される文字配列のサイズが strlen(dest)+strlen(src)+1 より小さい場合、動作は未定義です。つまり、`destsz` の誤った値は、予期されるバッファオーバーフローを露呈しません。
- すべての境界チェック付き関数と同様に、`strcat_s` は、実装によって `__STDC_LIB_EXT1__` が定義され、ユーザーが `<string.h>` をインクルードする前に `__STDC_WANT_LIB_EXT1__` を整数定数 `1` に定義した場合にのみ、利用が保証されます。
目次 |
[編集] パラメータ
| dest | - | 追加先のヌル終端バイト文字列へのポインタ |
| src | - | コピー元のヌル終端されたバイト文字列へのポインタ |
| destsz | - | 書き込む最大文字数。通常は宛先バッファのサイズ。 |
[編集] 戻り値
1) `dest` のコピーを返します。
2) 成功した場合はゼロを返し、エラーの場合は非ゼロを返します。また、エラー時には、`dest` がヌルポインタでないか、`destsz` がゼロまたは `RSIZE_MAX` より大きくない限り、`dest[0]` にゼロを書き込みます。
[編集] 注釈
`strcat` は呼び出しごとに `dest` の末尾を検索する必要があるため、`strcat` を使用して多数の文字列を1つに連結するのは効率が悪いです。
`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 The strcat function (p: 364)
- K.3.7.2.1 The strcat_s function (p: 617-618)
- C99標準 (ISO/IEC 9899:1999)
- 7.21.3.1 The strcat function (p: 327)
- C89/C90標準 (ISO/IEC 9899:1990)
- 4.11.3.1 The strcat function
[編集] 関連項目
| (C11) |
2つの文字列の指定された文字数を連結する (関数) |
| (C11) |
ある文字列を別の文字列にコピーする (関数) |
| (C23) |
指定された区切り文字で停止しながら、あるバッファを別のバッファにコピーする (関数) |
| C++ ドキュメント (strcat について)
| |