【问题标题】:checking EOF on unix cp program在 unix cp 程序上检查 EOF
【发布时间】:2015-04-04 10:46:49
【问题描述】:

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

【问题讨论】:

    标签: unix operating-system system-calls


    【解决方案1】:

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

    在文件结束时,read 返回0。仅当出现错误时才返回-1

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

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


    顺便提一下,在调用open 打开文件进行读取时,不需要0666 模式参数;这仅适用于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, ...);
    

    【讨论】:

    • 感谢您的回答!我在阅读手册页时错过了 read() 的返回值。此外,0666 参数修复了我在尝试检查输出文件时遇到的恼人的默认文件权限错误
    猜你喜欢
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 2019-04-23
    • 2019-11-13
    • 2014-11-18
    • 2016-03-23
    • 2018-08-01
    相关资源
    最近更新 更多