strcat は、string.hをインクルードすれば、利用できます。
しかし正しく利用するには、その関数がどのように作られたものかを理解する必要があります。
以下では、この関数の定義例と利用例を紹介します。
char a[10] = "abc";
strcat( a, "12345");
puts( a ); 実行結果⇒
abc12345
上記のでstrcatは、配列aに記憶される"abc"の後ろに、
"12345"に結合して、
配列aの記憶内容を"abc12345"の文字列へ変更しています。
関数内部では、第1引数の文字列最後の位置へ、第2引数の文字列をコピーしています。
s1の文字列最後の位置は、s1+=strlen(s1); で求められます。その位置にコピーすればよいので、次のような定義が可能です。 なお、戻り値は第1引数と同じです。
#include <stdio.h> #include <string.h> char * strcat(char *s1, char *s2) { char * startp = s1; s1 += strlen(s1); //ポインタを、s1の文字列の終端である'\0'が記憶される位置へ変更 */ strcpy(s1, s2); //それに、s2の文字列をコピー return startp; } main() { char a[10] = "abc"; char * p = strcat( a, "12345"); puts( p ); /* puts( a ); でも同じ */ }
その実行例を以下に示します。
abc12345
ここでは、添え字用変数を使かわずに、ポインタ引数の変数を変更することで、
コピーする位置を探し、次の文字コピーの繰り返しでも
コピー先、コピー元の対象を変更しています。
#include <stdio.h> #include <string.h> char * strcat(char *s1, char *s2) { char * startp = s1; while( s1 != '\0') {/* コピー先文字列の最後に移動する。*/ s1++; } while( ( *s1 = *s2 ) != '\0'){/* コピーする。*/ s1++; s2++; } return startp; } main() { char a[10] = "abc"; char * p = strcat( a, "12345"); puts( p ); /* puts( a ); でも同じ */ }
なおこの例において、aの配列要素は10個です。その中の3文字は記憶済みから始まっています。
残りリが7個ですが、文字列終端の'\0'を記憶することを考慮すると、残りは6個です。
よって、この場合6文字を超える文字列(例えば"1234567")を、
strcatの第2引数で指定すると、正しい実行が得られなくなります。
つまり、それは配列の範囲を超えたアクセスになるからです。
この関数も、関数定義例からもわかるように、
コピー元の文字列が記憶可能範囲を超えるサイズであっても、コピーしようとします。
つまり、
利用する方で正しく使わなければならない関数といえます。
上記strcatと同じ機能を行なわせる別の定義例を、以下に示します。
■■■■ の記述を正しく直して完成くだささい。
(なお、*のポインタ演算子を使わずに、[]の配列演算子を使ってください。つまり、添え字で位置を指定する形態です。
なお添え字変更は、後置インクリメントを使ってください)
←編集 入力後に クリックください。