1

EOFやファイルを使用するのはこれが初めてですが、コードがハングするという問題が発生しています。これは、EOFが何度もループしていることが原因であると考えられます。

私はファイルから代入していて、そのように動的にオブジェクトを作成していますが、ファイルが実行されるとハングします。

        while( !studentFile.eof() )
    {
        cout << "38\n";
        Student * temp = new Student();
        (*temp).input( studentFile );

        (*sdb).insert( (*temp) );           
    }

このコードのチャンクは、問題のコードです。カウト>>"38\ n"; 行番号と、それが何度もループすることからぶら下がっていると私が信じる理由です。

このファイルには4人分のデータしか含まれていませんが、38回は5回表示されます。これが、1回のループが多すぎると思われる理由です。データの最後のビットを取得すると、ファイルが終了したことを登録していないようで、再びループしますが、入力するデータがないため、コードがハングします。

これを修正するにはどうすればよいですか?私の論理は正しいですか?

ありがとうございました。

4

3 に答える 3

3

これは、EOFフラグが設定されるのは、データを読み取ろうとしてデータを取得しようとした場合のみであるためです。だからそれは行くだろう

Test for EOF -> No EOF
Try to read one line -> Good, read first line
Test for EOF -> No EOF
Try to read one line -> Good, read second line
Test for EOF -> No EOF
Try to read one line -> Good, read third line
Test for EOF -> No EOF
Try to read one line -> Good, read fourth line
Test for EOF -> No EOF
Try to read one line -> EOF

しかし、によってTry to read one line -> EOF、あなたはすでにwhile5回目の反復の本体にいるので、ループが5回実行されているのがわかります。したがって、EOFをチェックする前に読む必要があります。

于 2011-11-23T00:54:15.817 に答える
3

他の人はあなたが気づいた問題の詳細をすでに指摘しています。

ただし、まだ気付いていない問題が他にもあることを理解しておく必要があります。1つは、かなり明白なメモリリークです。ループのすべての反復は次のStudent * temp = new Student();ように実行されますが、一致するを実行することはありませんdelete

newC ++を使用すると、使用するすべてのオブジェクトを使用する必要がある他の言語(Javaなど)よりもメモリ管理がはるかに簡単になります。C ++では、オブジェクトを定義して使用するだけです。

Student temp;

temp.input(studentFile);

これにより、コードが簡素化され、メモリリークが排除されます。Studentオブジェクトは各反復の終了時に自動的に破棄され、(概念的には)新しい/異なるオブジェクトが次の反復の開始時に作成されます。

それ自体は実際にはバグではありませんが、それでもかなり単純化することができます。どうやらどのsdbポイントにもinsertメンバー関数があるので、標準のコンテナーのように使用できます(どちらの方法でも実際には問題ではありませんが、実際にはそうなる可能性があります)コードを整理するには、まず、:の抽出演算子を記述しますStudent

std::istream &operator>>(std::istream &is, Student &s) {
    s.input(is);
    return is;
}

次に、ストリームからコレクションにデータをコピーするだけです。

std::copy(std::istream_iterator<Student>(studentFile),
          std::istream_iterator<Student>(),
          std::inserter(*sdf));

これにより、EOFの正しい処理が自動化されるため、最初のように問題に対処する必要がまったくないことに注意してください(問題を引き起こしたくても、簡単ではありません)。

于 2011-11-23T01:12:44.157 に答える
0

ストリームに対して操作を実行した直後に、ストリームステータスビットを確認する必要があります。コードは表示されませんが(*temp).input(studentFile)、ストリームからの読み取りを行っているように見えます。読み取りを行った、読み取った(しようとした)データを処理する前に、呼び出しeof()(またはその他のステータスチェック)を行います。

于 2011-11-23T00:58:13.397 に答える