'读'系统功能的奇怪行为

时间:2015-12-08 12:18:09

标签: c

我尝试编写的程序应该能够读取长度不超过8个字符的字符串,并检查文件中是否存在这样的字符串。我决定使用'read'系统函数,但我想出了这个函数的奇怪行为。由于它是用手工编写的,它必须在文件结束时返回0,但在我的情况下,当没有更多的字符要读取时,它仍然读取'\ n'并返回1(读取的字节数)(I'检查了读取字符的ASCII码,它实际上是10,即'\ n')。所以考虑到这个事实,我改变了我的代码并且它有效,但我仍然无法理解为什么它会以这种方式运行。这是我的功能代码:

int is_present(int fd, char *string)
{
    int i;
    char ch, buf[9];

    if (!read(fd, &ch, 1)) //file is empty
        return 0;

    while (1) {
        i = 0;
        while (ch != '\n') {
            buf[i++] = ch;
            read(fd, &ch, 1);
        }
        buf[i] = '\0';
        if (!strncmp(string, buf, strlen(buf))) {
            close(fd);
            return 1;
        }
        if(!read(fd, &ch, 1)) //EOF reached
            break;
    }
    close(fd);
    return 0;
}

3 个答案:

答案 0 :(得分:1)

我认为您的问题出在内部read()调用中。在那里你没有检查功能的返回。

    while (ch != '\n') {
        buf[i++] = ch;
        read(fd, &ch, 1);
    }

如果文件在输入函数时恰好位于EOF且ch等于'\n',那么它将是无限循环,因为read()不会修改ch值。顺便说一下,你没有检查buf的界限。

答案 1 :(得分:0)

我假设问题是'为什么read()以这种方式工作' 而不是'我的错误是什么?程序'?

这不是错误。来自manual page

  

成功时,返回读取的字节数(零表示文件结束),文件位置按此编号前进。如果此数字小于请求的字节数,则不是错误;这可能发生在例如因为现在实际可用的字节数较少(可能是因为我们接近文件结尾,或者因为我们正在从管道或终端读取),或者因为read()被中断通过信号。出错时,返回-1,并正确设置errno。在这种情况下,未指定文件位置(如果有)是否发生变化。

如果您考虑一下read必须以这种方式工作。如果它返回0表示当某些数据已经被读取时已达到文件结尾,则您不知道已读取了多少数据。因此,read仅在由于文件结束条件而未读取数据时返回0。

因此,在这种情况下,只有\n可用,read()将成功并返回1.下一次读取将返回零以指示文件结束。

答案 2 :(得分:0)

read()函数除非找到EOF,否则会继续读取字符并将其放在缓冲区中。在这种情况下,\n也被视为一个角色。因此它也读到了。您的代码在阅读\n后会关闭,因为除了EOF之外别无其他。因此,只有EOFread()的分隔符,并且每个其他字符都被认为是正常的。干杯!