怠日記

写真・金魚・昆虫・プログラミングの趣味を語るサイトです。似たようなことをnoteにも書いたり書いてなかったり。

C言語 - 文字列を連結する | strcat(), strncat()

文字列を連結するには strcat() または strncat() を使う。

文字列を連結する

#include <string.h>
char *strcat(char *dest, const char *src);

引数

  • dest
    連結先の文字列

  • src
    連結する文字列

src は dest のヌル文字の位置から連結される。
文字列の長さはチェックされないので、事前にチェックを行い、オーバーフローを防ぐことが重要である。

戻り値

dest を指すポインタを返す。

char buf[128] = "Hello";

strcat(buf, " World!");
printf("%s\n", buf);
/* → Hello World! */

注意

文字列の長さはチェックされない。
連結する文字列の長さによってはオーバーフローする可能性がある。

/* "Hello" とヌル文字でバッファサイズ 6 で確保される */
char buf[] = "Hello";

/* バッファサイズが 6 の変数に対して、さらに7文字追加しようとしている */
strcat(buf, " World!");

文字列の長さチェックをしてから連結する。

「連結先のバッファサイズ - 連結先のバッファに格納された文字列の長さ - 1(ヌル文字の長さ)」が連結可能な最大の長さである。

その長さと連結する文字列の長さを比べて処理を分岐する。

char buf[16] = "Hello";
const char src[] = " World!";

if (sizeof(buf) - strlen(buf) - 1 >= strlen(src)) {
    /* 連結する文字列を入れる空きがある場合は連結する */
    strcat(buf, src);
} else {
    /* TODO:空きがない場合の処理を書く */
    printf("String concatenation failed.\n");
}

指定した文字数分の文字列を連結する

#include <string.h>
char *strncat(char *dest, const char *src, size_t count);

引数

  • dest
    連結先の文字列

  • src
    連結する文字列

  • count
    連結する文字数
    *連結先のバッファサイズと勘違いしないように。

戻り値

連結先の文字列(dest)を指すポインタを返す。

動き

dest のヌル文字の位置に src を連結する。

連結する文字数は count で指定した長さである。

もし count が src の長さより大きい場合、count の代わりに src の長さが使われる。

例: 連結する文字列より小さい数を指定した場合

” World!” から指定の3文字分 ” Wo” とヌル文字が連結される。

char buf[128] = "Hello";

strncat(buf, " World!", 3);
printf("%s\n", buf);
/* → Hello Wo */

例: 連結する文字列(ヌル文字除き)と同じ数を指定した場合

strncat(buf, " World!", 7);

コンパイル時に警告表示される。 ↓

warning: 'strncat' specified bound 7 equals source length [-Wstringop-overflow=]

ヌル文字も含めた長さを指定しなければならない。

例: 連結する文字列を超える数を指定した場合

連結する文字列とヌル文字が連結される。

strncat(buf, " World!", 10);
printf("%s\n", buf);
/* → Hello World! */

オーバーフローを避けるには

「連結先のバッファサイズ - 連結先のバッファに格納された文字列の長さ - 1(ヌル文字の分)」を count に指定する。

char buf[10] = "Hello";

strncat(buf, " World!", sizeof(buf) - strlen(buf) - 1);
printf("%s\n", buf);
/* → Hello Wor */

もし、すでにバッファサイズいっぱいに格納されていたら、何も連結されない。

char buf[6] = "Hello";

strncat(buf, " World!", sizeof(buf) - strlen(buf) - 1);
printf("%s\n", buf);
/* → Hello */

どのように組むのが正解かはケースバイケースだろう。

連結できる分だけ連結できれば OK のときもあれば、完璧に連結できなければ入力エラーとするときもある。