覚えておいてください:ではなく、をfgetc()
返します。戻り値のセットには、すべての可能な有効な文字と個別の(負の)EOFインジケーターが含まれているため、を返す必要があります。int
char
int
char
次のc
代わりにtypeforを使用する場合、2つのトラップが考えられますint
。
タイプchar
がコンパイラで署名されている場合は、有効な文字をEOFとして検出します。多くの場合、文字ÿ(y-umlaut、UnicodeではLATIN LOWER CASE Y WITH DIAERESIS、U + 00FF、ISO8859-1別名Latin1コードセットの16進コード0xFF)は、EOFと同等であると検出されます。有効な文字です。
タイプchar
が符号なしの場合、比較は真になりません。
どちらの問題も深刻であり、正しいタイプを使用することで両方を回避できます。
FILE *fp = fopen("file.txt", "r");
if (fp != 0)
{
int c;
int nl = 0;
while ((c = fgetc(fp)) != EOF)
if (c == '\n')
nl++;
printf("Number of lines: %d\n", nl);
}
FILE
タイプはであり、ではないことに注意してくださいFile
。を介して読み取る前に、ファイルが開かれていることを確認する必要があることに注意してくださいfp
。
CTRL + Dを明示的に指定すると、を使用してもEOFが検出されますchar c
。
これは、コンパイラがchar
符号付き型として提供することを意味します。また、ÿを含むファイルの行を正確にカウントできないことも意味します。
CP / MやDOSとは異なり、UnixはEOFを示すために文字を使用しません。読み取る文字がなくなると、EOFに到達します。多くの人を混乱させるのは、端末で特定のキーの組み合わせを入力すると、プログラムがEOFを検出することです。実際に起こることは、ターミナルドライバが文字を認識し、未読の文字をプログラムに送信することです。未読文字がない場合、プログラムは0バイトを返します。これは、ファイルの終わりに達したときに得られる結果と同じです。したがって、文字の組み合わせ(常にではありませんが、多くの場合Ctrl-D)は、プログラムに「EOFを送信する」ように見えます。ただし、使用している場合、文字はファイルに保存されませんcat >file
; さらに、control-Dを含むファイルを読み取る場合、それはバイト値0x04の完全に細かい文字です。プログラムがcontrol-Dを生成し、それをプログラムに送信する場合、それはプログラムへのEOFを示しません。これは厳密にはUnix端末(ttyおよびpty —テレタイプおよび疑似テレタイプ—デバイス)のプロパティです。