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:
- File ends without a newline character.
- File ends with a newline character.
Proof:
- Assume the
feof
is checked after thefgets()
, but beforefputs()
. Then it does not work for case 1. above, as whatever charactersfgets()
reads before the EOF, won't be used byfputs()
. - Assume
feof
is checked afterfputs()
, but beforefgets()
. Then it does not work for case 2. above, as whenfgets()
lastly encounters EOF, it does not overwrite the buffer string with anything new, and asfputs()
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.
精彩评论