我知道有两种方法可以刷新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被命中,因为它需要编辑命令。我想应该可以通过将终端设置为原始模式(未经过实验)来克服这个问题。然而,编辑功能将在原始模式下丢失。答案 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');
如果您使用stdin
来访问输入流,则可以使用以下内容忽略该行的其余部分。
while ( (c = fgetc(stdin)) != '\n' && c != EOF);
答案 1 :(得分:1)
仅使用C ++标准库功能,不支持完全丢弃,仅支持当前缓存/可用于stdin
的数据。
大多数时候,程序员只需要ignore
(参见该页面底部的示例)其余的有问题的行然后尝试下一个缓冲行。如果您担心可能存在许多有问题的行 - 例如,用户可能已经删除了您想要丢弃的废话页面,但是您确实希望让他们有机会输入更多行,当stdin
上的读取将阻塞时,您需要使用特定于操作系统的函数来计算。然后,您将ignore
行,直到阻止条件为true
。
select
和poll
是两个这样的操作,可以在大多数操作系统上运行,但是从内存中它们只为Windows上的套接字流定义,所以对你没用。 Cygwin可能会或可能不会以某种方式支持他们;如果你想尝试一下 - 只要ignore
文件描述符(0为0)测试可读,你就会stdin
行。您会发现许多其他问答,讨论如何查看是否有可用的输入:例如checking data availability before calling std::getline,Check if stdin is empty,Win32 - 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--"
这样的特定字符串,用户知道他们可以键入以停止丢弃行并切换回处理未来行