web-dev-qa-db-ja.com

ファイルの行ごとに読み取るfgets

FgetsがEOFまたは改行まで読み込まれることを理解しています。

ファイルから行を読み取るサンプルコードを作成したところ、fgetsが必要な回数よりも多く実行されることがわかりました。それは、ちょうど2行の空白行を持つ非常に単純なファイルです。 Enterキーを1回押して、ファイルを保存しました。

以下はコードです:

fp = fopen("sample.txt","r");
while (!feof(fp)) {
        fgets(line,150,fp);
        i++;
        printf("%s",line);
}
printf("%d",i);

ファイルに空白行が2つしかないため、whileループが2ではなく3回実行されるのはなぜですか?

8
codeara

あなたの場合、最後の行は一見2回読み込まれているようですが、そうではありません。 fgetsへの最後の呼び出しはNULLを返し、ファイルの終わりが読み取られたことを示します。バッファは更新されなかったため、これをチェックせず、バッファの古い内容を再度出力しません。

通常、feofをまったく使用せず、f...ファミリーの関数からの戻り値を確認することをお勧めします。

fp = fopen("sample.txt", "r");
while (1) {
        if (fgets(line,150, fp) == NULL) break;
        i++;
        printf("%3d: %s", i, line);
}
printf("%d\n",i);

関数feofは、読み取りを試みた後にtrueを返しますbeyondファイルの終わり。これは、読み取りを試みたfgetsへの最後の(失敗した)呼び出しの後でのみ発生します。 atまたはファイルの終わりの直前。この中の回答 long SO post 詳細を説明します。

18
M Oehm