Hello i had a simple copy file program in C but i cant explain why i get different output in the destination file when i use the 2nd method. The correct output with for loop:
I am the worst programmer in the world!
:D
And this is bla bla bla bla
more bla bla bla...
BUT with while loop a random char is generated in EOF:
I am the worst programmer in the world!
:D
And this is bla bla bla bla
more bla bla bla...
The code is
int main()
{
int i;
char ch;
create_files();
FILE *src = fopen("best.txt", "r");
FILE *dst = fopen("copied.txt", "w");
for(i=getc(src); i!=EOF; i=getc(src)) //correct copy
{
putc(i, dst);
}
/* while(!feof(src)) //woot?
{
ch=fgetc(src);
fputc(ch,dst);
}*/
fclose(dst);
fclose(src);
return 0;
}
void create_files()
{
FILE *fp;
fp = fopen("best.txt","w");
fprintf(fp,"I am the worst programmer in the world!\n:D\n And this is bla bla bla bla\n more bla bla bla...\n");
fclose(fp);
}
i ve used both fputc or putc and fgetc or getc and still the same. Did i forget something?
What
while (!feof(src)) {
ch=fgetc(src);
fputc(ch,dst);
}
does, is:
When EOF occurs, (3) is still executed before the check in (1) in the next iteration. The special value EOF
is converted to a char
and output.
The correct loop is
while ((ch = fgetc(src)) != EOF)
fputc(ch, dst);
assuming you give ch
the type int
, because a char
cannot represent EOF
. Note the assignment within the check; some programmers will tell you that's ugly, but so many use it that you might as well get used to it. Your variant for
loop is correct as well.
(Aside 1: fputc
is equivalent to putc
and fgetc
to getc
, as long as you don't try to use them in a function pointer context.)
(Aside 2: your while
loop also doesn't check for stream errors, while checking for EOF
returns catches that as well.)