2009-04-14 14 views
2

私はかなり最近、C++クラスのfriendキーワードとシリアル化での使用法を学びましたが、今は動作させるためにいくつかの助けが必要です。C++クラスのシリアル化

私のクラスをファイルにシリアライズするのに問題はありませんが、うまくいっていますが、このファイルをベクターコンテナに読み込もうとしています。私は、行ごとに読み込むコードではループが必要だと確信していますが、クラスには異なる型があるので、私はstd :: getline()を使うことはできません。また、そのアプローチはistreamメソッドを使用しません実装された? サンプル出力ファイルは次のようになります。

Person 1 
2009 
1 

Person 2 
2001 
0 

マイコード:

class SalesPeople { 
    friend ostream &operator<<(ostream &stream, SalesPeople salesppl); 
    friend istream &operator>>(istream &stream, SalesPeople &salesppl); 

    private: 
     string fullname; 
     int employeeID; 
     int startYear; 
     bool status; 
}; 

ostream &operator<<(ostream &stream, SalesPeople salesppl) 
{ 
    stream << salesppl.fullname << endl; 
    stream << salesppl.startYear << endl; 
    stream << salesppl.status << endl; 
    stream << endl; 
    return stream; 
} 

istream &operator>>(istream &stream, SalesPeople &salesppl) 
{ 
    stream >> salesppl.fullname; 
    stream >> salesppl.startYear; 
    stream >> salesppl.status; 
    // not sure how to read that empty extra line here ? 
    return stream; 
} 

// need some help here trying to read the file into a vector<SalesPeople> 
SalesPeople employee; 
vector<SalesPeople> employees; 

ifstream read("employees.dat", ios::in); 
if (!read) { 
    cerr << "Unable to open input file.\n"; 
    return 1; 
} 

// i am pretty sure i need a loop here and should go line by line 
// to read all the records, however the class has different 
// types and im not sure how to use the istream method here. 

read >> employee; 
employees.push_back(employee); 

ちなみに、私はしかし、私はどのようにシリアライズを習得しようとしている、Boostライブラリは、偉大なシリアライゼーションクラスを持っていることを知っています今のところSTLライブラリを使用して動作します。 私に与えることができ、正しい軌道に乗るための助けがあれば、事前に多くのことをありがとう!

答えて

2

すでに必要なコードをすべて手に入れているようです。あなたのコードをコピーし、それをコンパイルしてSalesPeopleをループ内のファイルから読み込むようにしました。私は以下の変更を加えますが、これはあなたの宿題のためですので、コードを見る前に次のヒントを読んで考えてください。

  • ループ内の営業担当者を読み取るために、私はあなたが このFAQを見てみることをお勧めします。それはあなたが 必要とするほとんど正確に の例を持っています。 FAQ 15.4もお手伝いします 、私は信じています。ファイルから を読み込むとき 余分な空白行を処理する方法のご質問については

  • 、この linkをチェックしてください。あなたは非常に簡単に この方法で空白を抽出することができます。

  • jfclavetteが示唆したように、あなたが1つの 文字列にそのライン上のすべてを必要とする 以来、私は 、 販売員のフルネームで読み取るため std::getlineに探してお勧めします。

あなたには1つの質問があります。従業員IDはどうですか?私はそれがあなたのサンプルコードで無視されていることがわかります。それは目的ですか? jfclavetteが示唆したように、いくつかを追加することは悪い考えではないかもしれない

istream &operator>>(istream &stream, SalesPeople &salesppl) 
{ 
    //stream >> salesppl.fullname; 
    getline(stream, salesppl.fullname); 
    stream >> salesppl.startYear; 
    stream >> salesppl.status; 
    // not sure how to read that empty extra line here ? 
    stream >> ws; 
    return stream; 
} 

while(read >> employee) 
{ 
    // cout << employee; // to verify the input, uncomment this line 
    employees.push_back(employee); 
} 

また、:

そして、あなたはまだ助けが必要な場合は、今、私はこの作業を取得するために書いたコードをチェックアウトすることができます入力の検証(ストリームの状態を読み込んだ後でストリームの状態を確認し、ストリームの状態が良好であることを確認します)。 FAQ 15.5の理由でwhile()ループを使用することをお勧めしますが、

+0

ありがとうございました!!!! これは多くの助けになりました!今私は間違っていることをはるかに良く理解しています。 また、私はwsについて考えていなかった、私は長い間それを行う方法が不思議でした!どうもありがとうございます! – nmuntz

+0

問題はありません。うれしいです! – Venesectrix

1

あなたの問題がわかりません。あなたは正確に何を理解していませんか?あなたの名前が複数のトークンで構成されているという事実?それを行う魔法の方法はありません、あなたは名前のトラフgetline()を取得することがあります。また、シリアル化するときにトークンの数を指定して、適切なトークン数を読み取ることもできます。つまり、あなたのファイルは見えるかもしれません。

2人1

私は人がここで最後の名前の最初の名前と1だったと仮定しました。 1つのファーストネームと1つのラストネームがあり、それぞれを別々に読んでいるという概念を強制することもできます。

while(!ifstream.eof())をループして読み込みます。もちろん、入力を常に検証する必要があります。

また、なぜ各レコードの間に追加のendlを追加していますか?シリアライズされたデータはきれいである必要はない。 :)

関連する問題