有两种方法我知道刷新标准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
。
select
和poll
是在大多数操作系统上可以使用的两个这样的操作,但是从内存来看,它们只是在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