我是新来的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);
}
Run Code Online (Sandbox Code Playgroud)
但是,我得到了一个无限循环.这是因为我从未真正打过一个名为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);
}
Run Code Online (Sandbox Code Playgroud)
或者,如果你不喜欢循环条件下的分配:
while (1) {
int c = fgetc(src);
if (c == EOF) break;
fputc(c, dst);
}
Run Code Online (Sandbox Code Playgroud)
无论如何,使用fread()和以块为单位读取和写入数据会更有效率fwrite(),例如:
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 */
}
Run Code Online (Sandbox Code Playgroud)
此外,包含一些错误检查是个好主意,因为读取和写入文件都会因各种意外原因而失败.您可以ferror()用来判断特定I/O流上是否发生了错误.