【问题标题】:Why doesn't tcflush work for scanf?为什么 tcflush 对 scanf 不起作用?
【发布时间】:2015-01-13 12:49:09
【问题描述】:

我有这个简单的代码来接受 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 接受回车。但是,如果在每个 scanf 之间使用 __fpurge(stdin);,则代码按预期工作。但是如果我使用read(STDIN_FILENO,&a,1); 而不是scanf,它就不起作用。对于read(),只有tcflush(STDIN_FILENO,TCIOFLUSH); 有效,但scanf 失败。谁能解释一下为什么?

【问题讨论】:

  • 你确定你打电话给__fpurge(STDIN_FILENO);还是__fpurge(stdin);

标签: c linux linux-device-driver


【解决方案1】:

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

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

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

所以在第一种情况下:使用scanf 清空 C 缓冲区效果很好,但在系统级别没有任何作用。

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

【讨论】:

  • 你能通过一个简单的例子解释一下C级缓冲区和系统级缓冲区是如何连接的吗?
  • 当您使用fread 时,从 C 缓冲区读取数据。如果此为空,则使用read 从系统重新填充。当您fwrite 数据被写入 C 缓冲区时。如果这个已满,则使用write 将数据刷新到系统中。只需考虑一下您管理口袋里的钱与银行账户的方式(pocket=c-buffer,bank=system;口袋里满了银行,口袋里空了,从银行里充值)......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
相关资源
最近更新 更多