2014-01-20 46 views
0

每當我在這裏提出一個問題時,結果都是一些非常愚蠢的錯誤(如果你不相信我,請查看我的歷史記錄),所以請耐心等待可以在這裏。C++ istream操作符>>錯誤數據處理

感覺好像我的問題應該很受歡迎,但是我找不到任何關於它的事情,我已經用盡了想法嘗試。

無論如何,事不宜遲:


我試着輸入超載operator>>。它應該在同一時間從文件中讀取一個整數跳過無效數據如char S,float S等

當然,我檢查if(in >> inNum)的get()的下一個標記檢查成功get()
如果成功,那裏就不多說了。
如果它失敗了,但是,我認爲一兩件事情發生了:

  1. 它偶然發現了一個非整數
  2. 它到達EOF

以下是我試圖解決它:

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()不消耗字符'a',也許in >> inNum也未能以某種方式消耗它。沒什麼大不了的,我只會嘗試一下。

這就是我在過去的2個小時裏所呆過的地方。我嘗試了istream :: ignore(),istream :: get(),ios :: rdstate來檢查文件中的eof,doublestring而不是char,以防char被數字讀取。

沒有用,我很絕望。

古怪足夠,該方法上述工作了以前的方案,我必須讀出的數據的條目的三重行上的格式的:stringintint
唯一的區別是我使用的ifstream對象爲那一個,和這個的一個istream對象。

紅利問題:當打嗝發生時,inNum的值爲0。我猜這是istream :: operator >>所做的事情?

+1

使用'in.clear();'清除任何錯誤標誌導致它再次嘗試編輯:還加上'CIN。忽略(STD :: numeric_limi ts :: max(),'\ n');'刪除被卡在流中的字符 – Gasim

+0

@Gasim我不確定你的意思。這是我在else {}中做的第一件事情。我應該在哪裏清除()'? – Kafeaulait

+0

對不起,閱讀編輯 – Gasim

回答

1

實現描述

  1. 嘗試讀取一個int
  2. 如果成功;
    1. 讀值插入到setB
    2. 下一個迭代
  3. 別人;
    1. 清除錯誤標誌
    2. 檢查,以便我們還沒有達到文件
    3. 仍然更多的數據結束了嗎? 下一次迭代

以上是你的函數的邏輯描述,但有若有所失......

如果我們嘗試讀取值,但失敗了,std::istream的手柄這些情況通過設置適當的錯誤標誌,但不會丟棄任何數據。

與您的實現問題是,當試圖讀取無效數據時,您將只嘗試再次讀取相同的無效數據..一遍又一遍,一遍又一遍,inf


解決方案

清除錯誤標誌後,可以使用std::istream::ignore從流丟棄任何數據。

功能的說法是潛在char s到忽略的最大數量,以及第二是「如果你打這個焦炭,不要忽略任何更多*。

讓我們忽略字符的最高金額,或直到我們打' '(空間):

#include <limits> // std::numeric_limits 

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