4

我已经做了一些cin操作,在我使用之前cin我想清除它的状态并刷新它。我该怎么做?我知道cin.clear()清除错误状态但要刷新cin 缓冲区我如何检查它是否为空,如果不是,我应该使用以下哪个语句来清空它,以便我cin以后可以安全地使用?

cin.ignore(std::numeric_limits<std::streamsize>::max()); 

或者

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
4

3 回答 3

6

看来,您检测到了一个问题,并且您想删除错误的输入,例如输入的行。您可以尝试删除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()of用作一个神奇的std::streamsize数字,表示不应将计数视为终止标准。如果您不传递终止字符,则流将忽略字符,直到流结束,这可能不是您想要的。

于 2013-10-19T19:09:32.393 回答
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());
}
于 2013-10-19T19:10:09.960 回答
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;
}
于 2015-07-17T09:37:24.250 回答