好的,这是一个愚蠢的问题,我相信我应该"知道这一点,但我不知道......
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}})。
我确信这是显而易见的,我真的很尴尬地问为什么。我以前从未跟read
跟scanf
。
我知道if [ $N -gt 0 ]; then expr 1 - $(expr $(expr 1 - $N) / 500); else expr $N / 500; fi
总体上是一个坏主意,但在我的情况下它是可以的,因为我控制管道的另一端,这对我来说很方便。
答案 0 :(得分:3)
stdin
流本身会执行read
来填充整个缓冲区,这可能是数千个字符宽。这不会为您的read
系统调用留下任何内容。 scanf
只是从该缓冲区中提取字符。
您后续的read
系统调用实际上返回0(由于文件末尾没有读取字节)而没有将任何数据放入c
,因此保留其值'b'
。你的程序没有注意到这种情况,因为它没有检查返回值。