C ++ istream运算符>>糟糕的数据处理

时间:2014-01-20 03:29:03

标签: c++ operator-overloading

每当我在这里问一个问题时,事实证明这是一个非常愚蠢的错误(如果你不相信我,请查看我的历史记录),如果你能在这里,请耐心等待。

感觉我的问题应该非常受欢迎,但我找不到任何关于它的内容,而且我已经没有想法尝试了。

无论如何,不​​用多说:


我正在尝试重载输入operator>>。它应该从文件中一次读取一个整数跳过char s,float等无效数据

当然,我正在检查if(in >> inNum) 获取()下一个标记检查是否成功获取get()。 如果成功,那就不多说了。
但是,如果它失败了,我认为发生了两件事之一:

  1. 偶然发现了一个非整数
  2. 它达到了eof
  3. 以下是我试图解决的问题:

    istream& operator>> (istream& in, SortSetArray& setB) {
        bool eof = false;
        int inNum = -1;
        while(!eof) {
            if(in >> inNum) {
                cout << "DEBUG SUCCESS: inNum = " << inNum << endl;
                setB.insert(inNum);
            }
            else {
                // check eof, using peek()
                // 1. clear all flags since peek() returns eof regardless of what
                //    flag is raised, even if it's not `eof`
                in.clear();
                cout << "DEBUG FAIL: inNum = " << inNum << endl;
                // 2. then check eof with peek()
                eof = (in.peek() == std::char_traits<char>::eof());
            }
        }
        return in;
    }
    

    该文件包含[1 2 3 4 a 5 6 7],程序自然会进入无限循环。 好吧,简单的猜测,peek()不会消耗char'a',也许in >> inNum也无法以某种方式消耗它。没什么大不了的,我只会尝试一下。

    这就是我过去2小时的情况。我尝试使用istream :: ignore(),istream :: get(),ios :: rdstate来检查文件中的eof,doublestring而不是char,以防万一{ {1}}以数字方式读取。

    什么都行不通,我很绝望。

    奇怪的是,上面的方法适用于以前的程序,我必须在格式的一行上读取三个数据条目:char string int
    唯一的区别是我为那个使用了int个对象,并为此使用了ifstream个对象。

    奖金问题:当打嗝发生时,inNum的值为0。我猜它是istream :: operator&gt;&gt;呢?

1 个答案:

答案 0 :(得分:1)

  

实施说明

     
    
        
  1. 尝试阅读int
  2.     
  3. 如果成功;     
          
    1. 将读取值插入setB
    2.     
    3. 下一次迭代
    4.     
  4.     
  5. 否则;     
          
    1. 清除错误标记
    2.     
    3. 检查以便我们尚未到达文件末尾
    4.     
    5. 还有更多数据? 下一次迭代
    6.     
  6.        

以上是你的功能的逻辑描述,但有些东西缺失......

如果我们尝试读取值但是失败,std::istream通过设置approriate错误标志来处理这些情况,但它不会丢弃任何数据。

您的实施问题是,在尝试读取无效数据时,您只会尝试再次读取相同的无效数据..过度,过度和过度, inf


<强>解决方案

清除错误标记后,您可以使用std::istream::ignore放弃流中的任何数据。

函数的 1st 参数是要忽略的潜在char的最大数量, 2nd 是“如果你点击 char ,不要再忽略*。

让我们忽略最大字符数,或者直到我们点击' '(空格):

#include <limits> // std::numeric_limits

in.ignore (std::numeric_limits<std::streamsize>::max(), ' ');