2012-05-22 1 views
1

Im은 언어 연습을위한 프로그램을 작성하지만, 나에게 맞는 코드에서 꽤 이상한 출력을 얻습니다.std :: fstream 파일 끝에 읽기가 끝나면 쓰레기를 인쇄합니다.

코드 :

#include <iostream> 
#include <fstream> 
#include <list> 
struct Car 
{ 
    std::string make; 
    std::string model; 
    int partNo; 
    double price; 
    int quantity; 
    std::string partname; 
}; 
void AddItem(); 
void _Update(int PartNo, int quantity); 
void UpdateList(std::list<Car>& _Car); 
int main() 
{ 
    std::list<Car> _Car; 
    UpdateList(_Car); 
    for(std::list<Car>::iterator iter = _Car.begin(); iter != _Car.end(); iter++) 
    { 
     std::cout << iter->make << " " << iter->model << " " << iter->partNo << " " << iter->price << " " << iter->quantity << " " << iter->partname << std::endl; 
    } 
} 

void UpdateList(std::list<Car>& _Car) 
{ 
    std::ifstream File("CarParts.txt"); 
    if(!File.is_open()) 
     std::cerr << "Bad file input....... closing...."; 

    while(!File.eof()) 
    { 
     Car tempObj; 
     File >> tempObj.make >> tempObj.model >> tempObj.partNo >> tempObj.price >> tempObj.quantity; 
     getline(File,tempObj.partname); 
     _Car.push_back(tempObj); 
    } 
    File.close(); 

} 

전초 기지 주어진 :

Pajero NA1H25 1 3.65 11 BLADE W/S WIPER Honda_Sivic R34gFk 2 4.97 15 
ENGINE CHANGE 2 4.97 15 

메모장 파일 :

Pajero NA1H25 1 3.65 11 BLADE W/S WIPER 
HondaSivic R34gFk 2 4.97 15 ENGINE CHANGE 

내가 실제로 인쇄 원했던 두 줄 아래에있는 세 개의 숫자입니까? 정말 혼란 스럽네요. 도와 줘서 고마워!

+0

게시 한 코드를 컴파일하고 실행하여 정상적으로 작동했습니다. –

+0

Jesse Good과 동일 ... 출력은 메모장 파일과 동일합니다. – AquilaRapax

답변

2

이것은 사람들이 C++에서 파일 데이터를 읽는 동안 자주 발생하는 문제입니다. 문제는 eof의 사용입니다. 이 플래그는 데이터 읽기 시도가 실패한 후에 만 ​​설정됩니다.

처음 두 줄을 읽은 후에도 여전히 파일의 끝에 도달하지 않았습니다. 읽을 수있는 내용이 있지만 eof은 설정되지 않았습니다. 그런 다음 세 번째 시간을 반복하고 2 줄을 읽은 다음 그 후에 끝냅니다. 문제는 그 세 번째 루프의 결과를 자동차 목록에 넣기 전에 eof을 확인하지 않는다는 것입니다.

eof 수표를 getline 호출 이후로 이동하거나 getline 반환 값을 사용할 수 있습니다. 예를 들어

: 데이터를 밀어 전에 성공적으로 읽은 여부를

while(true) 
{ 
    Car tempObj; 
    File >> tempObj.make >> tempObj.model >> tempObj.partNo 
     >> tempObj.price >> tempObj.quantity; 
    if (!getline(File,tempObj.partname)) break; 
    _Car.push_back(tempObj); 
} 

이 확인됩니다.

-3

std :: string 등의 구문을 피하기 위해 프로그램의 네임 스페이스를 std로 설정하십시오.

파일의 맨 위에있는 가져 오기에서 다음을 삽입하십시오. using namespace std;

파일에서 목록을 채우는 것이 목표 인 것처럼 보입니다.

이 부분에서 상대 :

File >> tempObj.make >> tempObj.model >> tempObj.partNo >> tempObj.price >> tempObj.quantity; 
getline(File,tempObj.partname); 

나는 더 나은 솔루션이 각 라인 withgetLine을 구문 분석하고 공간 분리 문자 또는 쉼표로 따라 데이터를 구문 분석하는 것입니다 생각합니다. 공백 구분 기호는 매우 까다 롭습니다.

+3

'파일 상단 부근에서 가져 오기에서 insert : using namespace std;'이것은 매우 나쁜 조언이며 버그를 가져올 수 있습니다. –

+0

getLine() callz를 사용하면 전체 행을 tempObj.partname 변수에 넣을 수 있습니다. –

+1

왜 std 네임 스페이스를 사용하는 것이 좋지 않은가요? 그것은 당신이 std lib에 포함되지 않은 것을 구현하지 않는다면 더 깨끗한 코드와 공통 네임 스페이스를 만든다. –