2011-08-10 7 views
0

개체 배열이 개인 변수 인 클래스에 대한 읽기 및 인쇄 기능을 정의해야합니다. 텍스트 파일에서 객체를 읽고 화면에 인쇄해야합니다. 이렇게하려면 < < 및 >> 연산자를 오버로드해야합니다. 배열에 저장된 정보를 읽고 인쇄하는 데 루프를 사용해야한다는 것을 알고 있지만이를 수행하는 방법을 모르겠습니다. 저의 강사는 기본적으로 함수 프로토 타입 인 스켈레톤 코드와 내가 지켜야 할 주요 기능을 제공했습니다. 나는 이것을 사용하여이 정확한 시나리오를 수행 했으므로 public struct와 어떻게 작동하는지 이해하지만 class의 private 변수가 나를 트립시킵니다.텍스트 파일에서 I/O 오버로드 및 읽기

class EmployeeList { 
public: 
    //Constructors 
    EmployeeList(); 
    EmployeeList(istream&); 
    //Accessors 
    bool isEmpty() const; 
    bool isFull() const; 
    int size() const; //Number of employees in list 
    Employee item(int i) const; //i'th employee 
    //Mutators 
    void setItem(int i,const Employee& e); 
    //I/O functions, sets the i'th emplyee to e 
    void read(istream&); 
    void print(ostream&) const; 

private: 
    enum {MAXSIZE = 100}; 
    Employee list[MAXSIZE]; 
    int count; //Number of employees in the current list 
}; 

EmployeeList::EmployeeList() { 
    count = 0; 
} 

EmployeeList::EmployeeList(istream& in) { 
    //list[MAXSIZE] = in; 
} 

bool EmployeeList::isEmpty() const { 
    return (count == 0); 
} 

bool EmployeeList::isFull() const { 
    return (count == MAXSIZE); 
} 

int EmployeeList::size() const { 
    return count; 
} 

Employee EmployeeList::item(int i) const { 
} 

void EmployeeList::setItem(int i, const Employee& e) { 
} 

void EmployeeList::read(istream& in) { 
    Employee tempList; 
    while (in >> tempList) { 
    } 
} 

void EmployeeList::print(ostream& out) const { 
    for (int i=0; i < size(); i++) { 
    } 

    cout << out; 
} 

위의 부분은 EmployeeList 클래스이며 아래 부분은 오버로드 함수입니다. 주석 처리 된 부분은 생각할 수 있지만 생각하지 못한 아이디어입니다.

istream& operator>>(istream& in, EmployeeList& l) { 
    l.read(in); 
    return in; 
} 

ostream& operator<<(ostream& out, const EmployeeList& l) { 
    l.print(out); 
    return out; 
} 

다음은 우리에게 주어진 주요 기능입니다.

int main() { 
    authorInfo(); 
    ifstream infile("a1in.txt"); 
    if(!infile) { 
     cout << "file 'alin.txt' not found."; 
     return EXIT_FAILURE; 
    } 
    EmployeeList theList(infile); 

    cout << endl; 
    cout << theList.size() << " employees read:\n" << theList << endl; 
    process(theList); 
    return EXIT_SUCCESS; 

} 

누군가가 올바른 방향으로 나를 조종 할 수 있기를 바랍니다. 더 많은 코드가 필요한 경우 알려 주시기 바랍니다. 감사!

EDIT : 직원 읽고 인쇄 기능 :

void Employee::read(istream& in) { 
    in >> name >> id >> salary; 
} 

void Employee::print(ostream& out) const { 
    out << getName() <<" "<< getID() <<" "<< getSalary() << endl; 
} 

직원 오버로딩 :

istream& operator>>(istream& in, Employee& e) { 
    e.read(in); 
    return in; 
} 

ostream& operator<<(ostream& out, const Employee& e) { 
    e.print(out); 
    return out; 
} 

EDIT 2 업데이트 판독() 함수. 잠시 동안의 줄은 오류가있는 곳입니다.

void EmployeeList::read(istream& in) { 
    Employee inEmployee; 
    while (in >> inEmployee && count < MAXSIZE) { 
     list[count] = inEmployee; 
     count++; 
    } 
} 

편집 3 : 여기까지 제가 가지고있는 print() 함수가 있습니다. 실제로 인쇄하지만 파일에서 정보가 아니라 기본 생성자 정보를 얻습니다. 읽기 또는 인쇄 기능 문제입니까? 나는 아직도 읽기 기능을 생각하고있다.

void EmployeeList::print(ostream& out) const { 
    cout << endl; 
    for (int i=0; i < count; i++) { 
     out << list[count]; 
    } 
} 
+0

왜 개인 변수가 당신을 트립합니까? 공개 섹션에서 필요한 정보는 모두 한 눈에 볼 수 있습니다. – BugFinder

+0

이름, ID 또는 급여의 공백은 Employee :: read를 깨뜨릴 것입니다. –

답변

1

배열 경계

을 유지 할, 당신은 :

Employee list[MAXSIZE]; 

이 주어 오류가 당신이 시도 코드가 :

EmployeeList::EmployeeList(istream& in) { 
    list[MAXSIZE] = in; 
} 

list의 요소는 list[0] ~ list[MAXSIZE - 1]. list[MAXSIZE]은 배열의 끝에서 1 개이며 유효하지 않습니다.

생성자, 내가 강하게 istream&하는 생성자를 가지고에 추천이라고 말했다

. 기본 생성자로 빈 객체를 생성 한 다음 read(istream&) 메소드 ( operator << 통해)를 사용하여 데이터를로드하는 것이 훨씬 낫습니다. 보다는 즉, :

EmployeeList theList(infile); 

사용 : 당신은 그냥 객체를 초기화 한 후 read() 전화를 가지고 istream&를 사용하는 생성자를 가질 필요한 경우

EmployeeList theList; 
infile >> theList; 

:

EmployeeList::EmployeeList(istream& in): count(0) { 
    read(in); 
} 

하나의 생성자 만이, 따라서 EmployeeList::EmployeeList()의 초기화는 EmployeeList::EmployeeList(istream&)에서 발생하지 않습니다. 나는이 불필요한 반복을 가지고 C++의 새로운 버전을 다루지 만, 당분간 그것이 우리가있는 곳이다.

또 다른 한가지 명명 : 당신의 코드가 더 나은 변수 이름 덜 혼란 스러울 것입니다. 이 경우 : 그것은 하지는 "일시적으로 목록을"때문에

void EmployeeList::read(istream& in) { 
    Employee tempList; 
    while (in >> tempList) { 
    } 
} 

그것은 읽은 단일 Employee있어, tempList 말을하지 마십시오. 더 좋을 것입니다 :

void EmployeeList::read(istream& in) { 
    Employee inEmployee; 
    while (in >> inEmployee) { 
    list[count++] = inEmployee; 
    } 
} 
+0

감사합니다 모두 매우 도움이되었습니다! – RedFred

+0

+1 건전한 조언이 있습니다. 나는'istream &'을 취하는 생성자 작성에 대한 권고에 동의하지 않는다. 스트림에서로드 된 불변 객체를 원한다면 가져 오는 좋은 방법이다. –

+0

나는 당신의 요지를 볼 수 있지만 다음과 같은 두 가지 이유로 그것을 추천 할 수있다 : 1) 적어도 기본 생성자의 코드 (C++ 11에서 고정)를 반복해야하므로 DRY를 위반하고 2)'istream'에서' EmployeeList'는 놀라 울 수 있습니다 ('explicit' 키워드를 사용하여 해결할 수 있습니다). 그래서 쇼 스토퍼는 아니지만 입문 과정 ("C++은 표준 C++이 아니며 두려움에 처해 있습니다")에 넣으려는 것들이 아닙니다. –

0

입력 방법을 알아 내서 시작할 수 있습니다.

EmployeeList::EmployeeList(istream& in) { 
    count = 0; 
    read(in); // delegate it to avoid duplication 
} 

void EmployeeList::read(istream& in) { 
    Employee tempList; 
    while (in >> tempList && count < MAXSIZE) { 
    list[count] = tempList; 
    ++count; 
    } 
} 

당신은이 작업을 할 수 Employee 클래스 operator>>를 오버로드해야합니다 내가 수행하게되는 가능성이 불완전 접근이입니다.

void EmployeeList::read(istream& in) { 

    Employee tempList; 
    while (in >> tempList) { 
    //here you are creating a tempList so after you fill in the values in tempList 
    //the tempList is to become a part of Employee list[MAXSIZE]; 
    } 
} 

어떻게 당신이 값을 입력 않습니다

+0

지금 컴파일 할 때 "in >> inEmployee '"에서'오류 : 일치하지 않음 '연산자 >>를 얻고 있습니다. 내 직원 클래스와 관련이 있습니까? 당신도 그걸 볼 수 있다면 도움이 될까요? – RedFred

+0

내가 제안한대로'Employee' 클래스에 대해'operator >>'을 과부하 시켰습니까? 코드에는 'EmployeeList' 클래스에 대한 오버로드 만 표시됩니다. –

+0

예 EmployeeList와 동일한 방식으로 사용합니다. – RedFred

0

이 그래서 난 그냥 당신에게 힌트를 제공하기 위해 노력할 것이다 숙제처럼 보인다?당신이 당신의 생성자를 사용하여 클래스에서 count

EmployeeList::EmployeeList(istream& in) { 
    //here... 
} 
0

다음은 해골 제한없이이 글을 쓰는 방법입니다. 귀하의 과제 요구 사항에 자유롭게 적응하십시오.

출처 : http://www.ideone.com/R9EeF

IOSTREAMS가 마스터하기 어렵다. std::getline, std::ios 플래그 및 stringstream을 읽어야합니다.이를 사용하여 직원 목록을 구문 분석하는 방법을 이해해야합니다.

iostreams에 대해 많은 이야기가 있기 때문에 작업 템플릿을 제공하는 것이 더 좋습니다 (내가 뼈대를 전혀 사용하지 않아 할당에 사용할 수 없음).

또한 실제 질문으로 내 대답을 향상시킬 수 있도록 질문을 주시기 바랍니다.

+0

저는 stringstream을 사용할 수 없다고 확신합니다. 또한 벡터를 사용할 수 없으므로 클래스를 사용해야합니다. 이 때문에 나는 정말로 내가 당신의 코드를 잘 따라갈 수 없다는 것을 알지 못한다. – RedFred

+0

@RedFred : 벡터를 사용합니다. 그렇지 않으면 읽기에 실패 할 경우 롤백하기가 매우 어렵 기 때문입니다. 또한 stringstream은 문자로 구분 된 문자열을 읽은 후에 매우 편리하지만 꼭 필요한 것은 아닙니다. 나는 반복한다. 올바른 istream 리더를 작성하는 것은 매우 귀찮다. 내가 보여준 코드는 올바르게 수행 할 수있는 방법을 보여주기위한 것이다. 그것은 (최소한 표면적으로) 이해되어 읽고, 템플리트로 사용되며, 복사되지 않고 과제에 붙여 넣기위한 것이 아닙니다. –

관련 문제