C++

2012-12-20 1 views
0

가능한 중복 :
End of File in C++C++

내가 .txt 파일에서 데이터를 읽을 수있는 기능을 썼다,하지만 난 그것을 호출 할 때, 계속 충돌합니다. 다음은 코드입니다 :

void beolvas(vector<int> &charge, vector<int> &deliver, vector<Robot*> &robots) { 
    string s; 
    ifstream f; 

    do { 
     cout << "Add meg a filenevet" << endl; 
     cin >> s; 
     f.open(s.c_str()); 
    } while (!f.good()); 

    cout << "adatok beolvasasa..." << endl; 

    int napok; 
    if (!(f >> napok)) throw 1; 
    charge.resize(napok); 
    deliver.resize(napok); 

    for (int i = 0; i<napok; i++) { 
     if (!(f>>charge[i])) throw 1; 
     if (!(f>>deliver[i])) throw 1; 
    } 

    string type, name; 
    int battery; 
    while (!f.eof()) { 
     cout << " a "; 
     if (f>>type && f>>name && f>>battery) { 
      if (type=="Mac") { 
       Mac r = Mac(name,battery); 
       robots.push_back(&r); 
      }; 
      if (type=="Eco") { 
       Eco r = Eco(name,battery); 
       robots.push_back(&r); 
      }; 
      if (type=="Pro") { 
       Pro r = Pro(name,battery); 
       robots.push_back(&r); 
      }; 
     }; 
    }; 
} 

문제가 while 루프에서 발생하는 것 같다. 3 행의 긴 텍스트를 읽으려는 경우 화면에 4 자의 a-s가 표시됩니다 (모든 행을 읽으려면 프로그램에서 인쇄합니다).

f.eof()은 내가 여기서 사용해야하는 기능이 아닙니까?

+0

'eof()'는 항상 잘못되었습니다. SO에는 수백 개의 복제본이 있습니다. –

답변

1

이것은 파일에서 읽는 데 가장 자주 발생하는 문제 중 하나입니다. f.eof()을 확인하면 이전에 읽기가 파일 끝에 도달했는지 여부 만 알 수 있습니다. 따라서 마지막으로 성공적으로 읽은 후 (세 번째 "a"가 인쇄 된 곳) eof()이 false를 반환하고 루프가 한 번 더 실행되어 추가 "a"가 출력됩니다.

대신, while 루프 상태로 추출 줄을 사용하십시오

이 당신의 추출 중 하나가 파일의 끝을 명중 때문에 빨리 같이 while 조건이 거짓이 될 것이다 작동
while (f>>type && f>>name && f>>battery) { 
    if (type=="Mac") { 
     Mac r = Mac(name,battery); 
     robots.push_back(&r); 
    } 
    if (type=="Eco") { 
     Eco r = Eco(name,battery); 
     robots.push_back(&r); 
    } 
    if (type=="Pro") { 
     Pro r = Pro(name,battery); 
     robots.push_back(&r); 
    } 
} 

루프가 실행되지 않습니다. 당신이 형식이 잘못된 선 후 계속하려면

, 난 당신이 대신 std::getline를 사용하는 것이 좋습니다

std::string line; 
while (std::getline(f, line)) { 
    std::stringstream ss(line); 
    if (ss >> type && ss >> name && ss >> battery) { 
    // ... 
    } 
} 
라인의 절반이 있다면 당신은 문제가 있었다 때문에이 std::getline 접근 방식을 사용하는 이유는

올바르게 포맷되었습니다. 귀하의 접근 방식은 아마도 typename을 읽었을 것이며, 그 결과는 battery에서 실패했으며, 루프의 다음 반복은 같은 위치에서 시작되었습니다.

자동 저장 기간이있는 객체에 대한 포인터를 일부 벡터로 푸시하는 경우에도 문제가 발생할 것입니다. 오브젝트가 작성된 블록이 종료되면 포인터는 유효하지 않은 오브젝트를 가리 킵니다.

+0

감사합니다 :) 하지만 "잘못된"줄을 발견하면 프로그램에서이 결과가 나타나지 않습니다. 올바른 양식으로 주어진 모든 줄을 읽고 싶습니다. – Andesz

+0

@ andesz2x4 제 편집을 참조하십시오. –

+0

대단히 감사합니다 : $ – Andesz

0

이것은 FAQ입니다. C/C++에서 파일 끝은 이후로 끝나면을 읽은 후에 만 ​​트리거됩니다. 따라서 feof() == false로 입력이 가능하다는 가정을 할 수 없습니다. 정확히 말하면 파일의 끝에있을 수 있기 때문에 은 아직입니다. 읽기 작업 후에 항상 유효한 입력 을 테스트해야합니다.