Fgets в C ++ повторяет последнюю строку - PullRequest
1 голос
/ 29 октября 2009

У меня есть программа вроде (из текст ссылки )

FILE* soubor;
char buffer[100];
soubor = fopen("file","r");
string outp = "";
while (! feof(soubor))
{
        fgets(buffer,100,soubor);
        fputs (buffer , stdout);
}
fclose(soubor);

и файл как

A
B
C
D
E

и вывод программы

A
B
C
D
E
E

повторяет последнюю строку файла дважды. У меня есть эта проблема и в других программах.

Ответы [ 4 ]

7 голосов
/ 29 октября 2009

Использование feof() в качестве условия для чтения цикла из файла почти всегда приводит к проблемам. Стандартный способ будет выглядеть так:

while (fgets(buffer, 100, infile))
    fputs(buffer, stdout);
7 голосов
/ 29 октября 2009

Проблема в том, что для последней строки fgets потерпит неудачу. Однако вы не проверяете feof до следующего цикла, поэтому вы все равно вызываете fputs, который будет печатать содержимое буфера, то есть предыдущую строку.

Попробуйте это:

FILE* soubor;
char buffer[100];
soubor = fopen("file","r");
string outp = "";
while (true)
{
  fgets(buffer,100,soubor);
  if (feof(soubor))
    break;
  fputs (buffer , stdout);
}
fclose(soubor);
0 голосов
/ 29 октября 2017

Причина, по которой feof (inputfile_pointer) не является правильным способом проверки завершения при копировании файла, заключается в том, что он не работает в ОБА в следующих ситуациях:

  1. Файл заканчивается без символа новой строки.
  2. Файл заканчивается символом новой строки.

Доказательство:

  • Предположим, что feof проверен после fgets(), но до fputs(). Тогда это не работает для случая 1. выше, так как все символы, которые fgets() читает перед EOF, не будут использоваться fputs().
  • Предположим, feof проверяется после fputs(), но до fgets(). Тогда это не работает для случая 2. выше, так как, когда fgets() в последний раз встречает EOF, он не перезаписывает строку буфера чем-то новым, а поскольку fputs() разрешено запускаться еще раз, он помещается в выходной файл то же содержимое строки буфера, что и в предыдущей итерации; следовательно, повторяется последняя строка в выходном файле.
0 голосов
/ 27 мая 2014

Мне нравится ответ Бена Рассела. Это моя версия, чтобы избежать повторения последней строки в коде c. Это работает, но я не понимаю почему, потому что условие if (fgets != NULL) должно делать эту работу.

int main ()
{
    FILE* pFile;
    char name[41] = "fileText04.txt";
    char text[81];
    int i;

    pFile = fopen("fileText04.txt", "wt");
    if (pFile == NULL)
    {
        printf("Error creating file \n");
        exit(1);
    }
    else
    {
        for (i=0; i<5; i++)
        {
            printf("Write a text: \n");
            fgets(text, 81, stdin);
            fputs(text, pFile);
        }
    }
    fclose (pFile);
    pFile = fopen(name, "rt");
    if (pFile == NULL)
    {
        printf("File not found. \n");
        exit(2);
    }
    while (! feof(pFile))
    {
        fgets(text, 80, pFile);
        if (feof(pFile))   // This condition is needed to avoid repeating last line.
            break;         // This condition is needed to avoid repeating last line.
        if (fgets != NULL)
            fputs(text, stdout);
    }
    fclose (pFile);
    return 0;
}

Большое спасибо, Хайме Давиу

...