4文字を超える文字を入力すると、余分な文字とnullターミネータが配列の末尾の外側に書き込まれ、配列に属していないメモリが上書きされます。これはバッファオーバーフローです。
Cは、所有していないメモリを壊すことを防ぎません。これにより、未定義の動作が発生します。プログラムは何でも実行できます。クラッシュしたり、他の変数を黙ってゴミ箱に捨てたり、混乱を招いたり、無害になったり、その他のことをしたりする可能性があります。プログラムが確実に動作するか、確実にクラッシュするという保証はないことに注意してください。すぐにクラッシュすることに頼ることさえできません。
これは、なぜscanf("%s")
危険であり、決して使用してはならないのかを示す良い例です。アレイのサイズがわからないため、安全に使用する方法がありません。代わりに、scanfを避け、 fgets()などのより安全なものを使用してください。
fgets()は、ストリームから最大で1つ小さいサイズの文字を読み込み、sが指すバッファーにそれらを格納します。EOFまたは改行の後で読み取りが停止します。改行が読み取られると、バッファに格納されます。終了ヌルバイト('\ 0')は、バッファーの最後の文字の後に格納されます。
例:
if (fgets(A, sizeof A, stdin) == NULL) {
/* error reading input */
}
厄介なことに、fgets()は、配列の最後に末尾の改行文字('\ n')を残します。したがって、コードで削除することもできます。
size_t length = strlen(A);
if (A[length - 1] == '\n') {
A[length - 1] = '\0';
}
うーん。単純な(しかし壊れた)ものscanf("%s")
は7行の怪物に変わりました。そして、それはその日の2番目のレッスンです。CはI/Oと文字列の処理が得意ではありません。それはできて、安全にできますが、Cはずっと蹴って悲鳴を上げます。