2

私は C の初心者です。この while ループを使用して、ファイルの内容を出力します。Linux では最後の行が 2 回出力されます。ファイルの最後に到達したときに while ループに入ってはなりません。Windows では問題ありません。

#include <stdio.h>
#include <unistd.h>

int main()
{

    char string[400];
    FILE *file_para;

    // Open the file
    if ((file_para = fopen("Test.txt", "r")) == NULL)
    {
        printf("cannot open file\n");
        getchar();
        return 0;
    }

    while (!feof(file_para))
    {
        fgets(string, 400, file_para);
        printf("**** %s", string);
    }

    fclose(file_para);
    getchar();
    return 0;
}
4

2 に答える 2

1

これは一般的なアンチパターンです:

while (!feof(file_para))
{
    fgets(string, 400, file_para);

feof()ファイルの終わりが原因で次の入力呼び出しが失敗するかどうかを検出しません。ファイルがすでにファイルの終わりに達しているかどうかがわかります。入力関数が既に失敗した後にのみ呼び出して、失敗した理由 (エラーまたはファイルの終わりの可能性があります) を確認する必要があります。

正しいパターンは次のとおりです。

while (fgets(string, 400, file_para))
{
于 2013-09-17T00:40:59.217 に答える
1

これは間違った使い方feof()です。feof()主な I/O 機能の 1 つが失敗した後、何が問題になったかを検出するために使用します。EOF に到達しようとしているかどうかは予測しません。一部の I/O 関数が既に EOF を報告したことを通知します。C はパスカルではありません。Pascal では、I/O 関数を呼び出す前に EOF をチェックできます (しなければなりませんか?)。

while (fgets(string, sizeof(string), file_para) != 0)
{
    ...do printing, etc...
}
// If you need to, use `feof()` and `ferror()` to sort out what went wrong.

どうしても の使用を主張する場合はfeof()、I/O 操作も確認する必要があります。

while (!feof(file_para))
{
    if (fgets(string, sizeof(string), file_para) == 0)
        break;
    ...do printing, etc...
}

が true に評価されない場合でもがferror(file_para)true と評価されるため、失敗する可能性があることに注意してください。feof(file_para)while (!feof(file_para) && !ferror(file_para))whilefeof()

于 2013-09-17T00:41:45.350 に答える