为什么 tcflush 对 scanf 不起作用?

Why doesn't tcflush work for scanf?

我有这个简单的代码来接受 3 个字符,:

char a,b,c;
scanf("%c",&a);
scanf("%c",&b);
scanf("%c",&c);
printf("%c",a);
printf("%c",b);
printf("%c",c);

我明白为什么这只接受 2 个字符,因为第二个 scanf 接受回车 return。但是,如果在每次 scanf 之间使用 __fpurge(stdin);,代码将按预期工作。但是如果我使用 read(STDIN_FILENO,&a,1); 而不是 scanf,它就不起作用了。对于 read(),只有 tcflush(STDIN_FILENO,TCIOFLUSH); 有效,但使用 scanf 失败。有人可以解释一下为什么吗?

fpurge 在 C 级别清空缓冲区,这是 scanf 工作的级别。

tcflush 在较低级别(系统级别)执行此操作,这是 read 工作的级别。

scanf 使用 read 填充它自己的缓冲区。

所以在第一种情况下:使用 scanf 清空 C 缓冲区效果很好,但在系统级别什么都不做。

在第二种情况下,清空系统缓冲区当然适用于 read 但不适用于 scanf,因为当您使用 scanf 时,数据至少到回车为止return 已经存在于 C 缓冲区中。第一个 scanf,读取大量数据,将它们放入缓冲区,然后使用该缓冲区 return 你只有一个字符。然后你 tcflush 刷新系统级缓冲区但不对 C 缓冲区执行任何操作,因此以下 scanf 能够在其中找到回车 return。