c - 为什么我的文件 IO 在 c 中无限循环?

标签 c file-io

我是 c 文件 IO 的新手。我决定用 c 编写一个简单的脚本,将一个文件复制到一个新文件中进行练习:

#include <stdio.h>

void main(int argc, char* argv[])
{
    if (argc != 3)
    {
        printf("Usage: ./myFile source destination");
        exit(-1);
    }

    FILE * src = fopen(argv[1], "r");
    if (src == NULL)
    {
        printf("source file not found", argv[1]);
        exit(-1);
    }

    FILE* dest = fopen(argv[2], "w");
    unsigned char c;
    do {
        c = fgetc(src);
        fputc(c, dest);
    } while (c != EOF);
}

但是,我得到了一个无限循环。这是因为我从未真正击中过名为 EOF 的角色吗?

此外,除了一次读取每个字符 1 之外,是否有更快的方法来编写此脚本?

最佳答案

c 声明为 int 它将起作用。

EOF 不是字符的有效值,因为如果是,文件中存在该字符可能会误导代码认为文件已经结束,而实际上并没有结束。这正是 fgetc() 实际上返回 int 而不是 char 的原因。


编辑:您的代码还有另一个错误:当 fgetc() 确实返回 EOF 时,您将该值传递给 fputc () 在结束循环之前,导致一个额外的字符出现在输出文件的末尾。 (额外的字符将是您在系统上将 EOF 转换为 unsigned char 时得到的任何字符,通常是字符 255 == 0xFF == (unsigned char) - 1.) 要解决这个问题,您可以像这样重写循环:

int c;
while ((c = fgetc(src)) != EOF) {
    fputc(c, dst);
}

或者,如果您不喜欢循环条件中的赋值:

while (1) {
    int c = fgetc(src);
    if (c == EOF) break;
    fputc(c, dst);
}

无论如何,使用fread()fwrite() 以 block 的形式读写数据会更有效率,例如像这样:

unsigned char buf[65536];
while (1) {
    int n = fread(buf, 1, sizeof(buf), src);
    fwrite(buf, 1, n, dst);
    if (n < sizeof(buf)) break;  /* end of file or read error */
}

此外,最好包含一些错误检查,因为读取和写入文件都可能因各种意外原因而失败。您可以使用 ferror() 判断特定 I/O 流是否发生了错误。

关于c - 为什么我的文件 IO 在 c 中无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19526172/

相关文章:

c++ - 在 Visual Studio 调试器中查看数组?

C编程: void * argument is it really pointer to anything,我可以在那里传递函数指针吗

游戏代码(这里是菜鸟程序员,仅供引用)

c - 生成随机 n 字节 Base64 字符串后的不可打印字符

c - 从 fgets 中删除换行符 - 不断出现段错误

database - Bash 在指定行编辑文件中的最后一个字符

c++ - 读取文件: handling lines differently

c++ - 许多小文件还是一个大文件? (或者,打开和关闭文件句柄的开销)(C++)

python - 将标题添加到文件

android - 读取和写入 XML 文件