C中的不同输出内容文件副本

时间:2012-01-13 22:13:52

标签: c file-copying fgetc getc

你好我在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。我忘记了什么吗?

5 个答案:

答案 0 :(得分:2)

什么

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

确实是:

  1. 检查EOF
  2. 读取一个字符,可能导致EOF
  3. 输出刚读过的字符,而不检查EOF。
  4. 当发生EOF时,在下一次迭代中的检入(1)之前仍然执行(3)。特殊值EOF将转换为char并输出。

    正确的循环是

    while ((ch = fgetc(src)) != EOF)
        fputc(ch, dst);
    

    假设您为ch提供int类型,因为char无法代表EOF。注意支票内的转让;一些程序员会告诉你这很难看,但很多人都会使用它,你可能会习惯它。您的变体for循环也是正确的。

    (除了1:fputc相当于putcfgetcgetc,只要您不尝试在函数指针上下文中使用它们。 )

    (除了2:您的while循环也不检查流错误,而检查EOF也会返回捕获。)

答案 1 :(得分:1)

您的while循环出现了一个错误。它读取/写入一个额外的字符,即奖励来自的地方 - 您将fgetc()返回的EOF值写入输出文件!

答案 2 :(得分:1)

第一个循环获取字符(可能检测到EOF),然后检查该值未检测到EOF并可能执行写入字符的块(直到读取了所有字符)。

第二个循环检查是否检测到EOF,取出角色(可能检测到EOF),写入角色(不考虑它可能是什么),并可能继续到下一个角色(如果EOF不是没有检测到。

在第二个循环中,在检查字符是否为EOF之前编写字符。

答案 3 :(得分:1)

while循环为您提供一个随机字符,因为在读取失败之前,EOF实际上没有被标记。那么你的while循环中发生了什么,你正在读取,fgetc失败,设置EOF,并返回一个duff值给你,然后你打印。

构造while循环的更好方法是:

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

答案 4 :(得分:0)

修改

看起来这不是实际问题,但我会将答案作为建议。


我唯一注意到的是:

char ch;

根据您的系统,char可以是签名或未签名,足以容纳EOF或不够。您的while循环可能表明您的操作系统适合后一种情况。

请改用int并尝试一下。