如何在从输入流中读取数据时清除failbit?

时间:2018-05-08 06:37:51

标签: c++

我正在尝试从输入流中读取整数,并且一旦读取字符(输入的一部分),就会设置failbit并停止读取我要清除failbit的流并读取下一个输入整数。我应该做些什么改变来获得正确的输出。

int main()
{
    int x;
    while(cin >> x)
    {
       if(cin.fail())
         cin.clear();
       cout << x;
    }
}

输入:12a34

预期输出:1234

实际输出:12

2 个答案:

答案 0 :(得分:1)

您遇到的问题是在检查eofbit之前未检查fail是否已设置。在测试EOF并清除流状态之前,您需要退出fail上的读取循环,例如。

#include <iostream>

int main (void) {

    int x = 0;

    while (1)       /* loop continually reading input */
    {
        if (! (std::cin >> x) ) {   /* check stream state */
            /* if eof() or bad() break read loop */
            if (std::cin.eof() || std::cin.bad())
                break;
            else if (std::cin.fail()) {     /* if failbit */
                std::cin.clear();           /* clear failbit */
                x = std::cin.get();         /* consume next char */
            }
        }
        else        /* on succesful read, just output int */
            std::cout << x;
    }
    std::cout << '\n';  /* tidy up with newline */
}

如果您先检查fail(),则会清除eofbit并继续阅读。

示例使用/输出

$ echo 12a34 | ./bin/cinint
1234

如果您想直接查看failbit,请使用rdstate()。在这种情况下,您可以确认failbit排除badbit,然后clear(),例如。

        if (! (std::cin >> x) ) {       /* check stream state */
            if (std::cin.rdstate() == std::ios_base::failbit) {
                std::cin.clear();       /* if failbit */
                x = std::cin.get();     /* consume next char */
            }
            else    /* else if eofbit or badbit - break read loop */
                break;
        }
        else        /* on succesful read, just output int */
            std::cout << x;

仔细看看,如果您有其他问题,请告诉我。

答案 1 :(得分:-1)

当找到无效字符时,while循环中的条件将失败。您还需要使用无效字符,否则下一次提取操作将再次失败:

int main()
{
    int x;
    while(true)
    {
       cin >> x;
       if(cin.eof())
       {
           break;
       }
       if(!cin)
       {
           cin.clear();
           //consume the invalid character
           cin.ignore();
           continue;
       }
       cout << x;
    }
}