次のコードが壊れていることはわかっています--getchar()返さintないchar--
良い!
char single_byte = getchar();
これは複数の方法で問題があります。
と仮定CHAR_BIT == 8しEOF == -1ます。(EOFが負であり、型がint;-1であることがわかっています。これは典型的な値です。実際、他の値を持つことは聞いたことがありません。)
プレーンcharは、署名付きまたは署名なしのいずれかです。
符号なしの場合、 のsingle_byte値は、読み取られたばかりの文字の値 ( として表され、unsigned char単純にプレーンに変換されますchar)、または に変換EOFした結果のいずれかになりcharます。通常EOFは -1 で、変換の結果は、または 255 になります。と実際の入力値 255CHAR_MAXを区別することはできません。また、すべてのバイト値が等しい確率で返されるため (そして枯渇することはありません) 。 、遅かれ早かれバイトが表示されます。EOF/dev/urandom0xff
しかし、それはあなたの入力ループを終了しません。あなたの比較(single_byte == EOF)は決して真実ではありません。このシナリオでsingle_byteは は符号なしタイプであるため、 と等しくなることはありませんEOF。のような無制限のデバイスからではなく、有限のファイルから読み取る場合でも、無限ループが発生します/dev/urandom。( と書くこともでき(single_byte == (char)EOF)ましたが、もちろんそれでは根本的な問題は解決しません。)
charループが終了するため、プレーンがシステムで署名されていると結論付けることができます。
プレーンcharが署名されている場合、事態はもう少し複雑になります。0..127 の範囲の文字を読み取った場合、その値は に格納されsingle_byteます。128..255 の範囲の文字を読み取ると、int値は;に変換されます。charはchar符号付きで、値が範囲外であるため、変換の結果は実装定義です。ほとんどの実装では、その変換は 128 を -128 に、129 を -127 に、... 255 を -1 にマップします。getchar()(通常) -1 を返す場合EOF、変換は明確に定義されており、-1 が返されます。EOF繰り返しますが、 と 値を持つ入力文字を区別することはできません-1。
(実際には、C99 の時点で、変換によって実装定義のシグナルが発生することもあります。幸い、私の知る限り、実際にそれを行う実装はありません。)
if (single_byte == EOF)
printf("EOF is implemented in terms of 0x%x.\n", single_byte);
繰り返しますが、この条件は、getchar()実際に返さEOFれた場合、または value を持つ文字を読み取った場合に true になります0xff。%x形式には type の引数が必要ですunsigned int。はほぼ確実に に昇格するsingle_byteタイプです。値が両方のタイプの表現可能な範囲内にある場合、値をフォーマットで出力できるようになりました。しかし、の値は( と等しいと比較しただけです) であるため、その範囲にはありません。の形式では、引数が型であると想定します(これは変換ではありません)。そして、の32ビット値を取った結果である可能性がありますcharintintunsigned intsingle_byte-1EOFprintf"%x"unsigned int0xffffffffint-1そして、それが本当にunsigned int.
getchar()の結果をオブジェクトに格納することは、 に格納intしたときに何が起こるかを分析するよりもはるかに簡単だったことに注意してくださいchar。