我是 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/