2014-01-20 1 views
0

내가 여기에 질문을 할 때마다, 아주 바보 같은 실수가된다. (당신이 나를 믿지 않는다면 나의 역사를 확인하라. 여기 있습니다.C++ istream 연산자 >> 불량 데이터 처리

내 질문이 매우 인기가 있어야한다고 생각하지만 그것에 대해 아무 것도 찾을 수 없으며 시도해 볼 아이디어가 부족합니다.

어쨌든, 속히 : 내가 입력 operator>> 과부하하기 위해 노력하고있어


. 그것은 char의, float의, 자연적으로

등 유효하지 않은 데이터를 건너 뛰는, 파일에서 한 번에 하나 개의 정수을 읽을하기로했다, 나는 모두 의 get() 다음의 토큰 if(in >> inNum)를 확인 해요get()을 확인하십시오.
성공하면 그다지 말할 것도 없습니다. 실패하면
는 그러나, 나는 두 가지 중 하나가 발생한다고 가정

  1. 그것은 여기

내가 처리하려고 방법 년대 EOF에 도달

  • 정수가 아닌 우연히 발견 it :

    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 시간 동안 있었던 곳입니다. 나는 파일에서 char 대신 istream :: ignore(), istream :: get(), ios :: rdstate를 시도하여 doublestring 대신 char을 숫자로 읽었을 때를 대비했다.

    아무것도 작동하지 않고 필사적입니다. 나는 형식의 라인에 데이터 항목의 삼중을 읽을 수 있었다 곳

    이 이상하게만큼, 접근 방식은 위의 이전 프로그램 일 : stringintint
    내가 그 하나에 대한 ifstream 객체를 사용하는 유일한 차이점은, 이 개체는 istream입니다.

    보너스 질문 : 딸꾹질이 발생하면 inNum의 값은 0입니다. 나는 istream :: operator >>가하는 일이라고 추측하고있다.

  • +1

    사용'in.clear을(); '을 일으키는 오류 플래그를 지우고 다시 시도 편집 : 또한'CIN를 추가합니다.. ignore (std :: numeric_limi ts :: max(), '\ n');'스트림에 갇혀있는 문자를 지우려면 – Gasim

    +0

    @Gasim 무슨 뜻인지 모르겠다. 그것이 else {} 본문에서 내가 한 첫 번째 것입니다. 내가 어디에서()'취소해야합니까? – Kafeaulait

    +0

    죄송합니다, 편집을 읽으십시오 – Gasim

    답변

    1

    구현 설명

    1. 성공하는 경우를 int
    2. 을 읽으려고;

    3. 다른 setB
    4. 다음 반복에 읽기 값을 삽입;
      1. 에러 클리어 플래그
      2. 검사가 있도록 우리는 파일
      3. 여전히 더 많은 데이터의 끝에 도달하지 않은? 다음 반복. 경우

        우리가 값을 읽을 수 있지만 실패하려고 ...

    위를 이 함수의 논리를 설명하지만,없는 뭔가가있다, std::istream의 핸들 이러한 경우에는 적절한 오류 플래그를 설정하지만 데이터를 버리지는 않습니다.

    잘못된 데이터를 읽으려고 시도 할 때 이상의 잘못된 데이터를 다시 읽으려고 시도하는 것입니다.


    솔루션

    오류 플래그를 삭제 한 후에는 스트림에서 데이터를 폐기 std::istream::ignore를 사용할 수 있습니다. *

    기능의 인수는 무시하는 잠재적 인 char의의 최대 개수, 그리고 는이 문자에 충돌하는 경우는 "더 이상 무시하지 않는 것입니다.

    하자 문자의 최대 금액을 무시하거나, 또는 우리가 ' ' (공간) 칠 때까지

    #include <limits> // std::numeric_limits 
    
    in.ignore (std::numeric_limits<std::streamsize>::max(), ' ');