Different output content file copy in C

放肆的年华 提交于 2019-12-11 02:36:09

问题


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?


回答1:


What

while (!feof(src)) {
    ch=fgetc(src);
    fputc(ch,dst);
}

does, is:

  1. check for EOF
  2. read a character, possibly causing EOF
  3. output the character just read, without checking for EOF.

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




回答2:


The first loop fetches the character (possibly detecting the EOF) and then checks the value didn't detect an EOF and possibly executes the block writing the character (until all characters have been read).

The second loop checks to see if an EOF was detected, fetches the character (possibly detecting an EOF), writes the character (without regard as to what it might be), and possibly continues onto the next character (if EOF wasn't detected).

In the second loop, you write the character before checking if it is a EOF.




回答3:


The while loop gives you a random character because EOF isn't actually flagged until a read fails. So what's happening in your while loop isyou do a read, fgetc fails, sets EOF, and returns a duff value back to you, which you then print.

A better way to structure the while loop would be:

ch=fgetc(src);
while (!feof(src)) {
   fputc(ch,dst);
   ch=fgetc(src);
}



回答4:


Your while loop has an off-by-one error. It reads/writes an extra character, which is where that bonus is coming from - you wrote the EOF value returned by fgetc() into the output file!




回答5:


Edit

Looks like this isn't the actual problem, but I'll keep the answer as an advice.


The only thing I noticed is:

char ch;

Depending on your system, char can be signed or unsigned, enough to hold a EOF or not enough. Your while loop is probably demonstrating that your OS fits in the latter case.

Use int instead and give it a try.



来源:https://stackoverflow.com/questions/8857963/different-output-content-file-copy-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!