开发者

Fgets in C++ repeats last line

I have program like (from 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);

and file like

A
B
C
D
E

and the output of program is

A
B
C
D
E开发者_如何转开发
E

it repeats last line of file twice. I have this problem in other programs too.


Using feof() as the condition for a loop to read from a file nearly always leads to problems. The standard way would look like this:

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


The problem is that for the last line, fgets will fail. However you aren't checking feof until the next loop, so you still call fputs which will print the contents of buffer, i.e. the previous line.

Try this:

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);


I like Ben Russels answer. This is my version to avoid repeating last line in c code. It works but I don't understand why, because the condition if (fgets != NULL) it should do this work.

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;
}

Many thanks, Jaime Daviu


The reason that feof(inputfile_pointer) is not the correct way to check for termination when copying the file, is because it does not work in BOTH of the following situations:

  1. File ends without a newline character.
  2. File ends with a newline character.

Proof:

  • Assume the feof is checked after the fgets(), but before fputs(). Then it does not work for case 1. above, as whatever characters fgets() reads before the EOF, won't be used by fputs().
  • Assume feof is checked after fputs(), but before fgets(). Then it does not work for case 2. above, as when fgets() lastly encounters EOF, it does not overwrite the buffer string with anything new, and as fputs() is allowed to run one more time, it will put in output file the same content of buffer string as in the previous iteration; hence repeated last line in output file.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜