C中的不同输出内容文件副本
您好我在C中有一个简单的复制文件程序,但我无法解释为什么当我使用第二种方法时,我在目标文件中得到不同的输出。 for循环的正确输出:
I am the worst programmer in the world! :D And this is bla bla bla bla more bla bla bla...
但是在while循环中,在EOF中生成一个随机字符:
I am the worst programmer in the world! :D And this is bla bla bla bla more bla bla bla...
代码是
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); }
我使用了fputc或putc和fgetc或getc,但仍然相同。 我忘了什么吗?
什么
while (!feof(src)) { ch=fgetc(src); fputc(ch,dst); }
的确是:
- 检查EOF
- 读一个字符,可能导致EOF
- 输出刚刚读取的字符,而不检查EOF。
当发生EOF时,在下一次迭代中的检入(1)之前仍然执行(3)。 特殊值EOF
将转换为char
和输出。
正确的循环是
while ((ch = fgetc(src)) != EOF) fputc(ch, dst);
假设你给ch
类型为int
,因为char
不能代表EOF
。 注意支票内的转让; 一些程序员会告诉你这很难看,但很多人都会使用它,你可能会习惯它。 您for
循环变量也是正确的。
(除了1: fputc
等同于putc
和fgetc
到getc
,只要你不尝试在函数指针上下文中使用它们。)
(除了2:你的while
循环也不检查流错误 ,而检查EOF
也会返回捕获。)
第一个循环获取字符(可能检测到EOF),然后检查该值未检测到EOF并可能执行写入字符的块(直到所有字符都被读取)。
第二个循环检查是否检测到EOF,取出字符(可能检测到EOF),写入字符(不考虑它可能是什么),并可能继续到下一个字符(如果未检测到EOF) )。
在第二个循环中,在检查字符是否为EOF之前编写字符。
while循环为您提供一个随机字符,因为在读取失败之前,EOF实际上没有被标记。 那么你的while循环中发生的事情是你执行读操作, fgetc
失败,设置EOF,并返回一个duff值给你,然后你打印。
构造while循环的更好方法是:
ch=fgetc(src); while (!feof(src)) { fputc(ch,dst); ch=fgetc(src); }
你的while
循环有一个off-by-one错误。 它读取/写入一个额外的字符,这是奖金
来自的地方 – 你将fgetc()
返回的EOF值写入输出文件!
编辑
看起来这不是实际问题,但我会保留答案作为建议。
我注意到的唯一一件事是:
char ch;
根据您的系统, char
可以是有符号或无符号的,足以容纳EOF或者不够。 你的while
循环可能certificate你的操作系统适合后一种情况。
请改用int
并尝试一下。