0

重複の可能性:
fgetc が EOF を識別しない
fgetc、EOF をチェック

ファイルを作成し、Unix で「file.txt」という名前を付けました。C プログラムからファイルの内容を読み込もうとしました。EOF 文字を受信できません。Unix はファイル作成時に EOF 文字を保存しませんか? もしそうなら、Cを使用してUnixで作成されたファイルからEOFを読み取る別の方法は何ですか.

コードサンプルはこちら

int main(){
File *fp;
int nl,c;
nl =0;
fp = fopen("file.txt", "r");
while((c = fgetc(fp)) != EOF){
  if (c=='\n')
    nl++;
}
return 0; 
}

CTRL+を明示的に指定Dすると、 を使用しても EOF が検出されますchar c

4

4 に答える 4

4

これは、 の型がcis char(およびcharコンパイラで符号なし、 in の値を調べることで確認できますCHAR_MIN) および notの場合に発生する可能性がありますint

の値はEOF、C 標準に従って負です。

したがって、暗黙的にキャストEOFするunsigned charと の真の値が失われEOF、比較は常に失敗します。

更新: 最初に対処しなければならない大きな問題があります。式c = fgetc(fp) != EOFfgetc(fp) != EOFは、 が最初に (0 または 1 に) 評価され、次に値が に代入されcます。ファイルに少なくとも 1 文字ある場合、fgetc(fp) != EOFは 0 と評価され、whileループの本体は実行されません。次のように括弧を追加する必要があります(c = fgetc(fp)) != EOF

于 2012-09-13T05:42:58.743 に答える
3

括弧がありません。次のようにする必要があります。

while((c = fgetc(fp)) != EOF)
于 2012-09-13T05:41:15.023 に答える
1

覚えておいてください:ではなく、をfgetc()返します。戻り値のセットには、すべての可能な有効な文字と個別の(負の)EOFインジケーターが含まれているため、を返す必要があります。intcharint

char次のc代わりにtypeforを使用する場合、2つのトラップが考えられますint

  1. タイプcharがコンパイラで署名されている場合は、有効な文字をEOFとして検出します。多くの場合、文字ÿ(y-umlaut、UnicodeではLATIN LOWER CASE Y WITH DIAERESIS、U + 00FF、ISO8859-1別名Latin1コードセットの16進コード0xFF)は、EOFと同等であると検出されます。有効な文字です。

  2. タイプ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 —テレタイプおよび疑似テレタイプ—デバイス)のプロパティです。

于 2012-09-13T05:55:03.130 に答える
0

変数を宣言する方法を示していcませintchar

于 2012-09-13T05:35:14.880 に答える