31

このコードで実行時の問題が発生する理由:

char stuff[100];
strcat(stuff,"hi ");
strcat(stuff,"there");

しかし、これはそうではありませんか?

char stuff[100];
strcpy(stuff,"hi ");
strcat(stuff,"there");
4

5 に答える 5

45

strcatnull ターミネータを探し、それを文字列の末尾として解釈し、そこに新しいテキストを追加し、その過程で 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.
于 2013-09-16T23:24:13.320 に答える
5

最初のケースでは、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 で埋められます (明確性が向上することは、パフォーマンス上の小さな問題に値する可能性があります)。

于 2013-09-16T23:25:08.750 に答える
2

stuffへの呼び出しの前に初期化されていないためですstrcpy。宣言stuffが空の文字列でない場合、それは初期化されていないデータです。

strcat文字列の末尾にデータを追加します。つまり、文字列内のヌル ターミネータを見つけ、その後に文字を追加します。初期化されていない文字列は、ヌル ターミネータを持つことが保証されていないためstrcat、クラッシュする可能性があります。

以下のように初期stuff化する必要がある場合は、strcat を実行できます。

char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");
于 2013-09-16T23:25:23.740 に答える
0

また、strcpyorstrcatを使用すると、意図しない問題が発生する可能性があるため、使用しないことをお勧めします。

とを使用するstrncpystrncat、バッファ オーバーフローを防ぐことができます。

于 2013-09-16T23:32:49.663 に答える
0

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];、それに頼るべきではありません。

于 2013-09-16T23:34:01.393 に答える