1

以下は、">>" 演算子をオーバーロードしたプログラムです。

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

class Student{
    public :
        string name;
        string entry_no;
};

class Science : public Student{
    public :
    float marks;
    void create_file();
    void highest();

    friend istream& operator >> (istream& input, Science& stud);
};

istream& operator >> ( istream& input, Science& stud){
    input >> stud.name;
    input >> stud.entry_no;
    input >> stud.marks;
    return input;
}
void Science::create_file(){
    ifstream file_read;

    file_read.open("student.txt");

    ofstream file_write;
    file_write.open("science.txt");
    string line;

    while(!file_read.eof()){
        getline(file_read,line,'\n');

        if(line.find("Science") != string::npos){
            file_write << line;
            file_write << '\n';
        }
    }
}

class Art : public Student{
    public :
    string marks;
    void create_file();
    void highest();
    friend istream& operator >> (istream& input, Art& stud);
};

istream& operator >> ( istream& input, Art& stud){
    input >> stud.name;
    input >> stud.entry_no;
    input >> stud.marks;
    return input;
}

void Art::create_file(){
    ifstream file_read;

    file_read.open("student.txt");

    ofstream file_write;
    file_write.open("art.txt");
    string line;

    while(!file_read.eof()){
        getline(file_read,line,'\n');

        if(line.find("Art") != string::npos){
            file_write << line;
            file_write << '\n';
        }
    }
    file_read.close();
    file_write.close();
}

void find_marks(){

    string entry_no;
    cout << "Enter entry_no of the student to find marks " << endl;
    cin >> entry_no;

    ifstream file_read;
    file_read.open("science.txt");
    string stud_entry;
    Science stud;
    bool found = false;
    if(file_read.is_open()){
        cout << (file_read >> stud) << endl;
    while( file_read >> stud ){
        cout << "hi";
        if(!entry_no.compare(stud.entry_no)){
            cout << stud.marks << endl;
            found = true;
            break;
        }
    }
    }
    else
        cout << "error in openning"<< endl;

    if(!found)
        cout << "this student does not exist" << endl;
}

int main(){
    Science science_stud;
    Art art_stud;

    science_stud.create_file();
    art_stud.create_file();
    find_marks();   
    return 0;
}

ここで、関数 find_marks() の while ループは、entry_no が一致しない場合、無限ループに入ります。なぜそれが起こっているのか誰でも説明できますか?

4

1 に答える 1

7

のテストeof()は、前の変換が失敗したためにエラーを出力するかどうかを判断する場合にのみ役立ちます。これは本当に悪いループ状態です:

  1. 必ずしも到達するとは限りません。たとえば、ある時点で変換が失敗した場合、ストリームは失敗状態になり、状態がクリアされるまでそれ以上の文字の抽出を拒否します。
  2. フラグは、std::ios_base::eofbitEOFに達したときに設定されません(少なくとも、設定されることが保証されているわけではありません)が、ファイルの終わりを超えて読み取ろうとした場合にのみ設定されることが保証されます。したがって、最後のデータセットは2回処理される傾向があります。

適切な方法は、データが読み取られたbool 後の変換を使用することです。

while (file >> whatever) {
    ...
}

C ++チュートリアルで使用するようにアドバイスされたeof()場合は、おそらくそれを焼き付けて、他の人にコピーを購入しないようにアドバイスする必要があります(焼き付ける必要があります)。もしあなたの先生があなたに使うように言ったらeof()-……まあ、燃えている人々は時代遅れになっていると私は理解しています。少なくとも、彼は間違っていると彼に言うべきです。

于 2012-11-04T18:41:08.430 に答える