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

9

下面是代码在现代 C++ 中的样子:

#include <string>
#include <istream>
#include <vector>

struct Student
{
    int ID;
    std::string name;
    std::string surname;
    int points;

    Student(int i, std::string n, std::string s, int p)
    : ID(i), name(std::move(n)), surname(std::move(s)), points(p) {}
};

std::vector<Student> read_students(std::istream & is)
{
    std::vector<Student> result;

    std::string name, surname;
    int id, points;

    while (is >> id >> name >> surname >> points)
    {
        result.emplace_back(id, name, surname, points);
    }

    return result;
}

用法:

#include <fstream>
#include <iostream>

int main()
{
    std::ifstream infile("test.txt");
    auto students = read_students(infile);

    // ...
}
于 2013-04-06T11:45:16.707 回答
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
}

您只分配了一个学生,每次循环时,您都在一遍又一遍地阅读它。

相反,您应该在每个循环上分配一个新学生并读入新分配的内存。

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 对象并且每次都覆盖其成员。解决方案是每次创建一个新的 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 回答