(Translated by https://www.hiragana.jp/)
strcat - Wikipedia

strcatは、ある文字もじれつべつ文字もじれつ連結れんけつ (concatenate) するC言語げんご関数かんすうである。 標準ひょうじゅんCライブラリ文字もじれつ操作そうさ関数かんすうぐん宣言せんげんされているヘッダーファイル string.hふくまれる。

書式しょしき

編集へんしゅう
#include <string.h>
char *strcat(char *s1, const char *s2);

s2が文字もじれつを、s1が配列はいれつ最後さいご連結れんけつする。もどは、s1のである。また、コピーさきとコピーもとかさなる場合ばあい動作どうさ未定義みていぎとする。

実装じっそうれい

編集へんしゅう
char *StrCat(char *s1, const char *s2)
{
    char *p = s1;
    while(*s1++);           /* s1を最後さいごまですすめる */
    while(*s1++ = *s2++);   /* s2をコピーする */
    return p;
}

バッファオーバーランの危険きけんせい対策たいさく

編集へんしゅう

strcatは、先程さきほどしめした実装じっそうれいてもかるとおり、s1の容量ようりょうについては一切いっさい関知かんちしない。よって、s1の配列はいれつ範囲はんいえて、s2がまれてしまうバッファオーバーランおそれがある。バッファオーバーランによってメモリが破壊はかいされたり、プログラムが異常いじょう動作どうさしたり、クラッシュしたりする危険きけんせいがある。簡単かんたん対策たいさくとして、事前じぜん領域りょういきちょう計算けいさん実行じっこうするれいしめす。

char s1[80] = "filename";
const size_t bufsize = sizeof(s1); /* 固定こていちょうchar配列はいれつ要素ようそすうもとめる */
const size_t s1len = strlen(s1);
const char* s2 = ".exe";
const size_t s2len = strlen(s2);
if (s1len + s2len + 1 <= bufsize) /* 1は終端しゅうたんNUL文字もじよう */
{
    memcpy(s1 + s1len, s2, s2len + 1);
    /* 以下いかでも可能かのうだが、さらに冗長じょうちょうとなるだけで意味いみはない。 */
    /*strcat(s1, s2);*/
    /*strncat(s1, s2, s2len);*/
}

strlen文字もじれつながさを事前じぜん取得しゅとくしているので、もはやstrcatを使用しようする必要ひつようはなく、memcpy十分じゅうぶんとなる。

うえれいでは、事前じぜんcharかた配列はいれつs1全体ぜんたいのバッファサイズすなわち要素ようそすうと、使用しよう領域りょういきながさおよびみに必要ひつよう領域りょういきながさを比較ひかくすることによって、配列はいれつきの容量ようりょうえたみ(バッファオーバーラン)をふせぐことができる。なお、さらに異常いじょうけい汎用はんよう目的もくてき考慮こうりょするならば、s1内容ないよう初期しょき終端しゅうたんNUL文字もじふくまれていない場合ばあいや、s1len + s2len + 1算術さんじゅつオーバーフローこしてしまう場合ばあいへの対処たいしょ必要ひつようとなってくる。

字数じすう制限せいげん文字もじれつ連結れんけつ関数かんすうとしてstrncat存在そんざいするが、さきのバッファサイズを指定していできるわけではないので、やはりstrcat同様どうよう危険きけんせいつことにわりはない。

代替だいたいとして、標準ひょうじゅんライブラリの一部いちぶではないがstrlcatやstrcat_sを使用しようすることのできる処理しょりけいもある。Microsoft Windows XP SP2以降いこう利用りよう可能かのうWindows APIのセーフ文字もじれつ関数かんすうでは、バッファサイズを指定していできるStringCchCat()StringCchCatN()用意よういされている[1]。 そのほか、単純たんじゅん文字もじれつ連結れんけつ用途ようととしてはややオーバースペックではあるが、C99標準ひょうじゅんされたsnprintf使用しようする方法ほうほうもある。

脚注きゃくちゅう

編集へんしゅう

関連かんれん項目こうもく

編集へんしゅう

外部がいぶリンク

編集へんしゅう