我如何刷新stdin? (环境:Mingw编译器,在Cygwin的xterm或mintty中运行)

有两种方法我知道刷新标准input:

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

但是,在我的环境中:

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

他们都没有工作。

我能做什么?

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

–UPDATE–

我怀疑Cygwin处理标准input分别比Windows本机标准input,使FlushConsoleInputBuffer()失败。

@wallyk:是的。 “flush”表示丢弃所有未读的缓冲input。

–UPDATE– (最终答案被接受,原因)

托尼D是对的。 问题是,Cygwinterminal是一个类似unix的terminal,它允许在“ENTER”键被击中之前进行编辑。 因此任何部分input必须被缓冲,并且在“ENTER”键被击中之前不会被传递给stdin,因为它期望编辑命令。 我想应该可以通过将terminal设置为原始模式(未经实验)来克服这一点。 然而,编辑function将在原始模式下丢失。

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

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

selectpoll是在大多数操作系统上可以使用的两个这样的操作,但是从内存来看,它们只是在Windows上为套接字流定义的,所以对你没用。 Cygwin可能会或可能不会以某种方式支持它们; 如果你想尝试它 – 只要stdin文件描述符(它是0)测试可读性,你就会ignore行。 你会发现许多其他问答讨论如何有可用的输入:例如在调用std :: getline之前检查数据的可用性 , 检查标准输入是否为空 , Win32 – 从标准输入读取超时

请记住,你的终端程序可能是内部缓冲你键入的内容,直到你按下ENTER键,所以你的程序最多可以清除早期的行,但不是用户部分输入的行(尽管你可以使用一些启发式的方法丢弃它,到你的程序的stdin )。

UPDATE

在某些情况下可能会更好的更酷的替代品:

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

  • 有一个特殊的字符串,比如说"--reset--" ,用户知道他们可以键入来停止丢弃行并切换回处理将来的行

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