在 unix cp 程序上检查 EOF

checking EOF on unix cp program

我正在编写一个 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 吗?感谢您的意见。

您应该阅读 read 函数的手册页。

在文件末尾,read returns 0。它 returns -1 仅当出现错误时。

read 可以读取的字节数少于您要求的字节数(如果剩余的字节数不多,则必须这样做)。您的 write 调用假设 read 实际读取了 BUFFER_SIZE 字节。

您需要保存 read 返回的结果并只写入那么多字节——并且您需要在 read returns 0 (指示文件结束)或 -1(指示错误)。在后一种情况下,您可能应该做一些事情来处理错误,或者至少通知用户。


顺便说一下,调用 open 打开文件进行读取时不需要 0666 模式参数;仅适用于 O_CREAT。由于 open 实际上是一个 variadic 函数(如 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, ...);