我正在编写一个unix cp程序,但我不清楚是否要检查EOF。我的代码是:
int main(int argc, const char * argv[]) {
int in, out;
char buf[BUFFER_SIZE];
if (argc != 3)
cout << "Error: incorrect number of params" << endl;
if ((in = open(argv[1], O_RDONLY, 0666)) == -1)
cout << "Error: cannot open input file" << endl;
if ((out = open(argv[2], O_WRONLY | O_CREAT, 0666)) == -1)
cout << "Cannot create output file" << endl;
else
while ((read(in, buf, BUFFER_SIZE)) != -1)
write(out, buf, BUFFER_SIZE);
return 0;
}
读取和写入很好,但在写入输出文件时写入了EOF。所以我在文件末尾有一些乱码。我只是没有正确检查EOF吗?我很感激输入。
答案 0 :(得分:4)
您应该阅读read
函数的手册页。
在文件结尾处,read
返回0
。只有在出现错误时才返回-1
。
read
可以读取比你要求的更少的字节(如果没有剩余的字节可以读取,它必须这样做)。您的write
电话会假定read
实际上已读取BUFFER_SIZE
字节。
您需要保存read
返回的结果并只写入那么多字节 - 并且当read
返回0
时需要终止循环(表示文件结束) )或-1
(表示错误)。在后一种情况下,您应该做一些事情来处理错误,或者至少告知用户。
顺便提一下,在调用0666
打开文件进行阅读时,您不需要open
模式参数;仅适用于O_CREAT
。由于open
实际上是可变参数函数(如printf
),因此您不必提供所有参数。
man page在这一点上并不清楚;它假装有两种不同形式的open
函数:
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
但实际上这在C中是不合法的。POSIX description正确地将声明显示为:
int open(const char *path, int oflag, ...);