C ++:如何从cin中删除错误的输入?

时间:2013-10-19 18:39:42

标签: c++ iostream

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

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

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

3 个答案:

答案 0 :(得分:5)

看来,您检测到了一个问题,并且想要摆脱错误的输入,例如输入的行。你可以试图摆脱std::cin在其缓冲区中的内容,但一般情况下,这不能很好地工作,因为无法保证流已读取,例如完整的行。另外,为了使其有用,您需要确保stdinstd::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;
}