2011-08-10 34 views
0

オブジェクトの配列をプライベート変数として持つクラスの読み込み関数と出力関数を定義する必要があります。テキストファイルからオブジェクトを読み込んで画面に出力する必要があります。これを行うには、< <と>>演算子をオーバーロードする必要があります。配列に格納された情報を読み取り、印刷するためにループを使用する必要があることは理解していますが、これをどのように達成するのかはわかりません。私の講師は、基本的に関数プロトタイプであるスケルトンコードと私が守るべき主な機能を与えてくれました。私は、これを使ってこの厳密なシナリオを実行したが、クラスのプライベート変数が私を引き上げているので、これが公共の構造体とどのように機能するのか理解しています。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:更新読み出し()関数。 whileとの行はエラーの場所です。

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

EDIT 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); 

が使用:他の言葉ではなく、中

EmployeeList theList; 
infile >> theList; 

あなたはちょうどそれは、オブジェクトを初期化した後read()を呼び出す必要があり、istream&を取るコンストラクタを持っているを必要としている場合

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

のコンストラクタは、と呼ばれ、 ではEmployeeList::EmployeeList()の初期化が行われません。私はこの不必要な繰り返しをC++の新しいバージョンで扱っていますが、当面はそれがどこにあるのかを聞いています。

もう一つの命名:あなたのコードは、より良い変数名と少ない混乱になります。この場合:それは「一時リスト」ではないだから

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

言ってはいけないtempList、それが読み込まれた単一Employeeです。

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

ありがとうございました。健全なアドバイスのためには – RedFred

+0

+1。私は 'istream&'をとるコンストラクタを書くことに対する推奨には反対しています。ストリームからロードされた不変オブジェクトが必要な場合は、それを得るための良い方法です。 –

+0

私はあなたの意見を見ることができますが、1)少なくともデフォルトのコンストラクタのコード(C++ 11で修正されています)と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

私は今コンパイルするときに "inEmployee 'の" in:in "in" in error ":演算子>>の" error:no match "を取得しています。これは私の従業員クラスと関係がありますか?あなたもそれを見ることができたら助けになるだろうか? – RedFred

+0

私が提案した 'Employee'クラスの' operator >> 'をオーバーロードしましたか?あなたのコードでは、 'EmployeeList'クラスのオーバーロードしか表示されません。 –

+0

はい私はEmployeeListと同じようにしています。 – RedFred

0

これには、私はあなたにヒントを与えることをしようとするでしょう宿題のように見えますか?あなたは、これはあなたのコンストラクタを使用して、あなたのクラスではcount

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

これは、スケルトンの制約なしで、これをどのように記述するかです。あなたの割り当て要件に自由に適応してください。

出典:http://www.ideone.com/R9EeF

入出力ストリームは、マスターするのは難しいです。 std::getlinestd::iosフラグとストリングストリームを読んで、従業員リストをパースする方法を理解する必要があります。

私は、iostreamについて多くのことが言えるので、スケルトンを全く使わないので、あなたの割り当てには使えない作業テンプレートを与えることを好む。

また、あなたの実際の問題で私の答えを高めることができるように、質問をしてください。

+0

私はstringstreamを使うことができないと確信しています。また、ベクトルを使用することはできません。クラスを使用する必要があります。このため、私は本当にあなたのコードをうまく追うことができないということを実際には知りません。 – RedFred

+0

@RedFred:そうでなければ、読み込みが失敗した場合にロールバックするのが非常に難しいので、私はベクトルを使用します。また、stringstreamは文字で区切られた文字列を読み込んだら非常に便利ですが、厳密には必要ではありません。私は繰り返します:正しいistreamリーダーを書くことは非常に面倒です。あなたが示すコードは、正しく行う方法を示すことを意図しています。それは、(少なくとも表面的に)理解され、テンプレートとして読み込まれ、あなたの課題にコピーされて貼り付けられることは意図されていません。 –

関連する問題