6

Cプログラミング言語から:

int c;
while ((c = getchar()) != EOF)
    putchar(c);

「...解決策は、getchar入力がなくなったときに固有の値を返すことです。この値は、実際の文字と混同できない値です。この値は、「ファイルの終わり」に対して と呼ばれます。大きな型であることをEOF宣言する必要があります返さcれる値を保持するのに十分です.可能な.getcharcharcEOFchar

stdio.hシステムに EOF の値をチェックインして出力したところ、 に設定されてい-1ます。私のシステムでcharsは署名されていますが、これはシステムに依存することを理解しています。だから、私のシステムEOFに合うことができcharます。c上記の小さなルーチンを aと定義して書き直したところchar、プログラムは意図したとおりに動作しました。のように振る舞うように見える 255 に対応する空白文字を持っているように見えるASCII文字テーブルの文字もありますEOF

では、なぜ ASCII には EOF に指定された文字 (255) があるように見えるのでしょうか? これは、 C プログラミング言語の本で述べられていることと矛盾しているようです。

4

5 に答える 5

3

getchar() のマニュアルによると、常に int 値を返します。

#include <stdio.h>
...
int getchar(void);
...
RETURN VALUE
fgetc(), getc() and getchar() return the character read as 
an unsigned char cast to an int or EOF on end of file or error.

したがって、int の代わりに char を使用すると、切り捨て (int -1 (0xffffffff) が char -1 (0xff) になる) が発生し、エラーが発生する可能性があります。

于 2013-10-31T20:37:11.407 に答える
2

これがどのように機能するかを理解するには、getchar を書いている人が何を考えているか想像してみてください。ファイルを読み取る必要があります。ルーチンを作成することから始めます。例:

unsigned char get_me_a_byte(file)... // 0..255

ファイルからすべてのバイトを読み取りたい場合:

unsigned char c;

while( c = get_me_a_byte(file) ) // while( (c = get_me_a_byte(file)) != 0 )
{
  ... do sth
}

問題は、z ゼロに遭遇すると停止することですが、すべてが赤くなったら停止したいということです。ファイルは一連のバイトと考えることができます。get_me_a_byteが 16 または 32 ビット型を返すことができるとしたら? 次に、バイトがファイルの終わりマーカーとして保持できない値を使用できます。

ビンゴ

決定はあなた次第なので、次のことが考えられます。

int get_me_a byte_U(file) ... // returning bytes as 0..255
int get_me_a byte_S(file) ... // returning bytes as -128..127

これで、次のことができます。

int c;
while( (c = get_me_a_byte_U(file) != UUU ) ....

ここで、UUUは、プラットフォームの 256 から MAXINT までのいずれかになります。

同様に:

int c;
while( (c = get_me_a_byte_S(file) != SSS ) ....

ここで、SSSは MININT..-129 および 128..MAXINT のいずれかです。

最初の方法を選択した場合、質問があります: UUU (EOF) の値はどうあるべきですか?

(-1) は EOF に適しています。これは、変数のビット幅に関係なく、変数に割り当てることができる (-1) ままになるためです。「remain -1」とは、常にすべて 1 のパターンになることを意味します。

char c = -1; // c = 11111111b / 0xFF / 255 (assuming your char is signed 8bit)
short s = -1; // s = 1111111111111111b / 0xFFFF / 65535
int i = -1; // s = 11111111111111111111111111111111b / 0xFFFFFFFF / 4294967295

今、それは明らかなはずです。

于 2013-10-31T22:00:16.423 に答える