C中不同输出内容的文件复制

发布于 2024-12-26 12:20:18 字数 1007 浏览 5 评论 0原文

你好,我有一个简单的 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 并且仍然相同。我是不是忘记了什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦过后 2025-01-02 12:20:18

作用

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

是:

  1. 检查EOF
  2. 读取一个字符,可能导致EOF
  3. 输出刚刚读取的字符,而不检查EOF。

当EOF发生时,(3)仍然在下一次迭代中签入(1)之前执行。特殊值 EOF 被转换为 char 并输出。

正确的循环是

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

假设您给ch类型为int,因为char不能表示EOF< /代码>。注意检查中的分配;有些程序员会告诉你这很丑陋,但是很多人都在使用它,所以你最好还是习惯它。您的变体 for 循环也是正确的。

(旁白1:fputc相当于putcfgetc相当于getc,只要你不尝试在函数指针上下文中使用它们。)

(旁白 2:您的 while 循环在检查 EOF错误 > return 也捕获了这一点。)

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

骷髅 2025-01-02 12:20:18

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

第二个循环检查是否检测到 EOF,获取字符(可能检测到 EOF),写入字符(不管它可能是什么),并可能继续到下一个字符(如果未检测到 EOF) )。

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

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.

北凤男飞 2025-01-02 12:20:18

while 循环给你一个随机字符,因为 EOF 实际上不会被标记,直到读取失败。因此,在 while 循环中发生的情况是,您执行读取操作,fgetc 失败,设置 EOF,并向您返回一个 duff 值,然后将其打印出来。

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

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

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);
}
两相知 2025-01-02 12:20:18

您的 while 循环存在差一错误。它读取/写入一个额外的字符,这就是额外的 的来源 - 您将 fgetc() 返回的 EOF 值写入到输出文件中!

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!

柠檬色的秋千 2025-01-02 12:20:18

编辑

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


我唯一注意到的是:

char ch;

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

请改用 int 并尝试一下。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文