Namespaces
Variants

strcat, strcat_s

From cppreference.net
< c ‎ | string ‎ | byte
定義先ヘッダ <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関数

関連項目

二つの文字列の特定の文字数を連結する
(関数)
文字列を別の文字列にコピーする
(関数)
(C23)
バッファを別のバッファにコピーし、指定された区切り文字の後で停止する
(関数)