Question

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.

Was it helpful?

Solution

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

OTHER TIPS

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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top