为什么 read() 在 scanf() 之后不起作用?
why doesn't read() work after scanf()?
好的,这是一个愚蠢的问题,我确定我 "should" 知道这个,但不知何故我不知道...
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
和 read
。
我知道 scanf
总的来说是个坏主意,但在我的情况下还可以,因为我控制着管道的另一端,而且这样做对我来说很方便。
stdin
流本身将执行 read
来填充整个缓冲区,这可能有数千个字符宽。这对您的 read
系统调用没有任何影响。 scanf
只是从缓冲区中提取字符。
您随后的 read
系统调用实际上是 returning 0(由于文件末尾没有读取字节)并且没有将任何数据放入 c
,因此保留其值'b'
。您的程序没有注意到这种情况,因为它没有检查 return 值。
好的,这是一个愚蠢的问题,我确定我 "should" 知道这个,但不知何故我不知道...
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
和 read
。
我知道 scanf
总的来说是个坏主意,但在我的情况下还可以,因为我控制着管道的另一端,而且这样做对我来说很方便。
stdin
流本身将执行 read
来填充整个缓冲区,这可能有数千个字符宽。这对您的 read
系统调用没有任何影响。 scanf
只是从缓冲区中提取字符。
您随后的 read
系统调用实际上是 returning 0(由于文件末尾没有读取字节)并且没有将任何数据放入 c
,因此保留其值'b'
。您的程序没有注意到这种情况,因为它没有检查 return 值。