为什么在scanf()之后没有读取()工作?

时间:2017-09-25 02:49:07

标签: c posix

好的,这是一个愚蠢的问题,我相信我应该"知道这一点,但我不知道......

FILE结构包装文件描述符,所以如果我fscanf应该推进文件描述符。

但是这个程序编译为foobar

#include <stdio.h>
#include <unistd.h>

int main() {
    char c;

    scanf("%c", &c);
    printf("scanned %c\n", c);

    read(STDIN_FILENO, &c, 1);
    printf("read %c\n", c);

    read(STDIN_FILENO, &c, 1);
    printf("read %c\n", c);
}

>echo bcd | ./foobar
scanned b
read b
read b

出现文件描述符没有前进,因为第一个read读取b。更令人惊讶的是,第二个也读取b(即使,如果我省略scanf,则第一个read读取b,第二个读取c scanf 1}})。

我确信这是显而易见的,我真的很尴尬地问为什么。我以前从未跟readscanf

我知道if [ $N -gt 0 ]; then expr 1 - $(expr $(expr 1 - $N) / 500); else expr $N / 500; fi 总体上是一个坏主意,但在我的情况下它是可以的,因为我控制管道的另一端,这对我来说很方便。

1 个答案:

答案 0 :(得分:3)

stdin流本身会执行read来填充整个缓冲区,这可能是数千个字符宽。这不会为您的read系统调用留下任何内容。 scanf只是从该缓冲区中提取字符。

您后续的read系统调用实际上返回0(由于文件末尾没有读取字节)而没有将任何数据放入c,因此保留其值'b'。你的程序没有注意到这种情况,因为它没有检查返回值。