在unix cp程序上检查EOF

时间:2015-02-04 19:08:02

标签: unix operating-system system-calls

我正在编写一个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吗?我很感激输入。

1 个答案:

答案 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, ...);