我怎样才能冲洗stdin? (环境:Mingw编译器,运行于xg或Cygwin的薄荷)

时间:2015-08-24 03:31:04

标签: c++ windows cygwin

我知道有两种方法可以刷新stdin:

(1)bool FlushConsoleInputBuffer(_In_ HANDLE hConsoleInput);    (2)fflush (stdin);

但是,在我的环境中:

Compiler: MinGW  g++
Running in: Windows, Cygwin xterm or Cygwin mintty

它们都不起作用。

我该怎么办?

注意:如果我的程序在dos提示窗口下运行,FlushConsoleInputBuffer()可以正常工作。另外,FlushConsoleInputBuffer()在Cygwin xterm或mintty上运行时很好地返回false。

- UPDATE -

我怀疑Cygwin分别处理stdin而不是Windows native stdin,这会导致FlushConsoleInputBuffer()失败。

@wallyk:是的。 '冲洗'表示删除所有未读缓冲的输入。

- 更新 - (接受最终答案和理由)

托尼D是对的。问题是Cygwin终端是类似unix的终端,允许在“输入”之前进行编辑。钥匙被打了。因此,任何部分输入都必须被缓冲,并且在“输入”之前永远不会传递给stdin。 key被命中,因为它需要编辑命令。我想应该可以通过将终端设置为原始模式(未经过实验)来克服这个问题。然而,编辑功能将在原始模式下丢失。

2 个答案:

答案 0 :(得分:1)

fflush旨在与输出流一起使用。 fflush(stdin)的行为未定义。请参阅http://en.cppreference.com/w/cpp/io/c/fflush

如果您使用std::cin访问stdin,则可以使用std::istream::ignore()忽略流中的内容,直至达到给定数量的字符或给定字符。

示例:

// Ignore the rest of the line.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

工作代码:http://ideone.com/Z6zLue

如果您使用stdin来访问输入流,则可以使用以下内容忽略该行的其余部分。

while ( (c = fgetc(stdin)) != '\n' && c != EOF);

工作代码:http://ideone.com/gg0Az2

答案 1 :(得分:1)

仅使用C ++标准库功能,不支持完全丢弃,仅支持当前缓存/可用于stdin的数据。

大多数时候,程序员只需要ignore(参见该页面底部的示例)其余的有问题的行然后尝试下一个缓冲行。如果您担心可能存在许多有问题的行 - 例如,用户可能已经删除了您想要丢弃的废话页面,但是您确实希望让他们有机会输入更多行,当stdin上的读取将阻塞时,您需要使用特定于操作系统的函数来计算。然后,您将ignore行,直到阻止条件为true

selectpoll是两个这样的操作,可以在大多数操作系统上运行,但是从内存中它们只为Windows上的套接字流定义,所以对你没用。 Cygwin可能会或可能不会以某种方式支持他们;如果你想尝试一下 - 只要ignore文件描述符(0为0)测试可读,你就会stdin行。您会发现许多其他问答,讨论如何查看是否有可用的输入:例如checking data availability before calling std::getlineCheck if stdin is emptyWin32 - read from stdin with timeout

请记住,您的终​​端程序可能在内部缓冲您键入的内容,直到您按ENTER键,因此最多您的程序可以清除较早的行,但不能清除用户部分键入的行(尽管您可以使用某种启发式方法将其丢弃在它发送到您的程序stdin)之后。

<强> 更新

在某些情况下可能足够好的替代品:

  • 保存now()时间,然后循环调用getline(std::cin, my_string)直到它失败(例如stdin上的EOF)或读取之间的时间大于某个阈值 - 比如说半一秒;这样,可能消耗已经缓冲但不需要的输入,但是在丢弃循环终止后,ENTER可能会发生进一步的手动用户输入:你可以提示ala std::cout >> "bad input discarded - you may press ^U to clear your input buffer if it contains unwanted text...\n";Control-U适用于许多终端,但请检查您自己的

  • 有一个像"--reset--"这样的特定字符串,用户知道他们可以键入以停止丢弃行并切换回处理未来行