このコードで実行時の問題が発生する理由:
char stuff[100];
strcat(stuff,"hi ");
strcat(stuff,"there");
しかし、これはそうではありませんか?
char stuff[100];
strcpy(stuff,"hi ");
strcat(stuff,"there");
strcat
null ターミネータを探し、それを文字列の末尾として解釈し、そこに新しいテキストを追加し、その過程で null ターミネータを上書きし、連結の最後に新しい null ターミネータを書き込みます。
char stuff[100]; // 'stuff' is uninitialized
null ターミネータはどこにありますか? stuff
は初期化されていないため、NUL で始まるか、その中に NUL が含まれていない可能性があります。
C++ では、次のことができます。
char stuff[100] = {}; // 'stuff' is initialized to all zeroes
'stuff' の最初の文字がヌル ターミネータであるため、strcat を実行できるようになり、適切な場所に追加されます。
C では、「もの」を初期化する必要があります。これは、いくつかの方法で実行できます。
char stuff[100]; // not initialized
stuff[0] = '\0'; // first character is now the null terminator,
// so 'stuff' is effectively ""
strcpy(stuff, "hi "); // this initializes 'stuff' if it's not already.
最初のケースでは、stuff
ごみが含まれています。 strcat
宛先とソースの両方に適切なヌル終了文字列が含まれている必要があります。
strcat(stuff, "hi ");
コピーを開始するstuff
終了文字をスキャンします。見つからない場合は、配列の末尾から実行され、任意の悪いことが発生する可能性があります (つまり、動作は未定義です)。'\0'
"hi "
この問題を回避する 1 つの方法は次のとおりです。
char stuff[100];
stuff[0] = '\0'; /* ensures stuff contains a valid string */
strcat(stuff, "hi ");
strcat(stuff, "there");
stuff
または、空の文字列に初期化できます。
char stuff[100] = "";
これにより、 の 100 バイトすべてstuff
が 0 で埋められます (明確性が向上することは、パフォーマンス上の小さな問題に値する可能性があります)。
stuff
への呼び出しの前に初期化されていないためですstrcpy
。宣言stuff
が空の文字列でない場合、それは初期化されていないデータです。
strcat
文字列の末尾にデータを追加します。つまり、文字列内のヌル ターミネータを見つけ、その後に文字を追加します。初期化されていない文字列は、ヌル ターミネータを持つことが保証されていないためstrcat
、クラッシュする可能性があります。
以下のように初期stuff
化する必要がある場合は、strcat を実行できます。
char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");
Strcat は、既存の文字列に文字列を追加します。文字列配列が空の場合、文字列の末尾 ( '\0'
) が検索されず、実行時エラーが発生します。
Linux のマニュアル ページによると、単純な strcat は次のように実装されています。
char*
strncat(char *dest, const char *src, size_t n)
{
size_t dest_len = strlen(dest);
size_t i;
for (i = 0 ; i < n && src[i] != '\0' ; i++)
dest[dest_len + i] = src[i];
dest[dest_len + i] = '\0';
return dest;
}
この実装でわかるように、正しい c 文字列値に初期化されてstrlen(dest)
いない限り、 は正しい文字列長を返しません。dest
で最初の値が 0 の配列があれば幸運かもしれませんがchar stuff[100];
、それに頼るべきではありません。