C ++中的Fgets重复最后一行

时间:2009-10-29 10:32:50

标签: c++ file fgets

我有类似的程序(来自link text

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 个答案:

答案 0 :(得分:7)

问题是,对于最后一行,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);

答案 1 :(得分:7)

使用feof()作为循环从条件读取的条件几乎总会导致问题。标准方式如下:

while (fgets(buffer, 100, infile))
    fputs(buffer, stdout);

答案 2 :(得分:0)

我喜欢Ben Russels的回答。这是我的版本,以避免重复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;
}

非常感谢, Jaime Daviu

答案 3 :(得分:0)

在复制文件时,feof(inputfile_pointer)不是检查终止的正确方法的原因是因为它在以下情况的 BOTH 中不起作用:

  1. 文件以没有换行符结尾。
  2. 文件以换行符结尾。
  3. 证明:

    • 假设在feof之后但在fgets()之前检查fputs()。然后,对于上面的案例1,它不起作用,因为在{EOF之前fgets()之前读取的任何字符fputs()都不会被feof使用。
    • 假设在fputs()之后fgets()之前检查fgets()。然后它不适用于上面的情况2.因为当fputs()最后遇到EOF时,它不会用任何新的覆盖缓冲区字符串,并且当{{1}}被允许再运行一次时,它将会在输出文件中输入与上一次迭代相同的缓冲区字符串内容;因此在输出文件中重复了最后一行。