文字列を連結するには 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 のときもあれば、完璧に連結できなければ入力エラーとするときもある。