我已经完成了一些cin
操作,在我使用cin
之前,我想清除它的状态和
冲洗它。我该怎么做?我知道cin.clear()
会清除错误状态,但要清除cin
缓冲区如何检查它是否为空,如果不是,我将使用哪个以下语句清空它以便以后可以安全地使用cin
?
cin.ignore(std::numeric_limits<std::streamsize>::max());
或
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
答案 0 :(得分:5)
看来,您检测到了一个问题,并且想要摆脱错误的输入,例如输入的行。你可以试图摆脱std::cin
在其缓冲区中的内容,但一般情况下,这不能很好地工作,因为无法保证流已读取,例如完整的行。另外,为了使其有用,您需要确保stdin
和std::cin
未同步,否则std::cin
永远不会缓冲任何字符:
std::ios_base::sync_with_stdio(false);
// read data using std::cin
if (!std::cin) {
// clean-up
std::cin.clear();
if (std::cin) {
std::cin.ignore(std::cin.rdbuf()->in_avail()); // ignore what is buffered
}
}
in_avail()
是否将返回非零值完全取决于使用的流缓冲区,并且它可能忽略了比实际想要忽略的更多。例如,如果替换std::cin
的流缓冲区以使用std::istringstream
的流缓冲区,则它可能会消耗此源中的所有字符。
最明智的清理可能是ignore()
下一个字符或当前行中的字符,使用
std::cin.ignore();
或
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
max()
的{{1}}用作神奇数字,表示不应将该计数视为终止条件。如果你没有传递终止字符,流将忽略字符,直到流的结尾可能不是你想要的。
答案 1 :(得分:1)
流缓冲区具有in_avail
方法。但是试着简单地删除内容,无论如何。:
template <class charT, class traits>
std::basic_istream<charT, traits>&
empty_buffer(std::basic_istream<charT, traits>& is)
{
std::basic_streambuf<charT, traits>* p = is.rdbuf();
p->pubseekpos(0, std::ios_base::in);
return is.ignore(std::numeric_limits<std::streamsize>::max());
}
答案 2 :(得分:1)
实际上,可以使用is_avail()方法完成此操作。 试试这个:
#include <iostream>
int empty_stream(std::istream & is) {
std::streambuf * pbuf = std::cin.rdbuf();
std::streamsize size = pbuf->in_avail();
if(size)
{
if(!is.good())
return 0;
is.sync();
return 1;
}
else
return -1;
}
int main() {
char str[50];
std::cin >> str;
switch(empty_stream(std::cin))
{
case -1:
std::cout << "Empty buffer" << std::endl;
break;
case 0:
std::cout << "Error flags in stream" << std::endl;
break;
case 1:
std::cout << "Buffer flushed" << std::endl;
break;
}
std::cin.get(); //This shouldn't be bypassed
return 0;
}