4

ファイルから構造体を読み込んでおり、それらを構造体のベクトルに追加したいと考えています。外観と動作は次のとおりです。

    typedef struct
{
    int ID;
    string name;
    string surname;
    int points;
}
Student;

int main()
{
    ifstream theFile("test.txt");
    std::vector<Student*> students;

    Student* s = new Student();

    while(theFile >> s->ID >> s->name >> s->surname >> s->points)
    {
        studenti.push_back(s); // here I would like to add this struct s from a file
    }

// here I want to print each struct's values on the screen, but the output is always ONLY last struct N times, and not all of them, each only once


    std::vector<Student*>::const_iterator it;
    for(it = students.begin(); it != students.end(); it+=1)
    {
        std::cout << (*it)->ID <<" " << (*it)->name << " " << (*it)->surname <<" " << (*it)->points <<endl;
    }

構造体をベクターに追加して通常どおりに出力するにはどうすればよいですか (この出力は、構造体がベクターに適切にロードされているかどうかを確認するだけです)。

4

4 に答える 4

8

あなたの間違いはポインターを使用することです

std::vector<Student> students;

Student s;
while(theFile >> s.ID >> s.name >> s.surname >> s.points)
{
    students.push_back(s);
}

これで動作します。

問題は、同じポインターを何度も再利用していたことです。したがって、すべて同じオブジェクトを指しているポインターのベクトルになります。最後に読み込まれた学生の値が含まれます。

単純な方が正しいのに複雑な方を選択するのは、かなり一般的な初心者の特徴のように思われるので、ポインターを使用することを選択した理由を知りたいと思います。

于 2013-04-06T11:41:05.267 に答える
0

ベクトルには学生ではなく学生へのポインタを格納したいので。

Student* s = new Student();

while(theFile >> s->ID >> s->name >> s->surname >> s->points)
{
    students.push_back(s); // here I would like to add this struct s from a file
}

生徒を 1 人だけ割り当てて、ループするたびに何度も読み込んでいます。

代わりに、各ループに新しい学生を割り当て、新しく割り当てられたメモリに読み込む必要があります。

Student* s;
int tmpId, tmpPoints;
string tmpname, tmpsur;

while(theFile >> tmpId >> tmpname >> tmpsur >> tmpPoints)
{
    s = new Student();

    s->ID = tmpId ;
    s->name = tmpname;
    s->sur = tmpsur ;
    s->points= tmpPoints;

    studenti.push_back(s); // here You push a pointer to the newly allocated student
}
else
{
    // There is error reading data
}

ベクターが不要になったら、忘れずに各生徒を削除してください。

于 2013-04-06T11:46:25.330 に答える
0

Student オブジェクトが 1 つあり、そのメンバーを毎回上書きするため、コードは機能しません。解決策は、毎回新しい Student オブジェクトを作成し、それへのポインターをベクターに渡すことです。

std::vector<Student*> students;
int tmpId, tmpPoints;
string tmpname, tmpsur;

while(theFile >> tmpId >> tmpname >> tmpsur >> tmpPoints)
{
    Student* s = new Student();
    s->ID = tmpId ;
    s->name = tmpname;
    s->sur = tmpsur ;
    s->points= tmpPoints;

    students.push_back(s); // push a pointer to new student object
}
else
{
    // ...
}
于 2013-04-06T12:00:00.607 に答える