【问题标题】:Using vector of user defined class type objects使用用户定义的类类型对象的向量
【发布时间】:2012-04-02 16:13:54
【问题描述】:

致力于解决 C++ 中的一个简单问题,想了解如何在实例化该对象向量时使用用户定义类类型的对象向量,而无需分配固定(最坏情况)数量的元素。即

目前我必须使用

vector<grades> students(10000); 

其中 10000 是我假设的记录的最大值。 如果某个文件有更多记录,它显然会崩溃。

所以在下面的代码的情况下,如何增加我的类对象的向量 动态读取我的类变量中的记录。 我不能使用 push_back(),如下面的代码所述。或者我该如何使用 push_back() ?

下面的代码应该解释 -

class grades
{
public:
    string mName;
    string mSurname;
    int mAge;
    string mLocation;
    int mMarks;
    char mGrade;

    //void readdata();
    void calcgrade();
    void showgrade(string name_surname);

};

    using namespace std;
    int main(int argc,char *argv[])
    {
        **vector<grades> students(10000);// I do not want to do this but make it dynamic**
        ifstream infile;
        char c;
        int i=0;
        int no_of_records=0;

        infile.open(argv[1],ios::in);
        if(infile.is_open() != true)
        {
            cerr << "Error opening input data file:" <<argv[1] << "...exiting\n";
            exit(-1);
        }

            while(!infile.eof()) 
            {
                 infile >> students[i].mName;//Can i use push_back() here and for reading all below entities, to make vector grow dynamically
                infile >> students[i].mSurname;
                infile >> students[i].mAge;
                infile >> students[i].mLocation;
                infile >> students[i].mMarks;
                i++;
                no_of_records++;
            }

            for(i=0;i<no_of_records;i++)
            {
               //Do some functions on each object students[i] in the vector 
            }
}

仅供参考:- 我在 C++ 中读取了一个文本文件,其中包含以下条目(实体的顺序和一行中不同类型实体的数量是固定的,我知道,但行数可能因不同的输入文件而异待读):

Name1 Surname1 Course1 Marks1
Name2 Surname2 Course2 Marks2
Name3 Surname3 Course3 Marks3
...
...

编辑:处理各种虚假空格、记录实体中的制表符的代码

while(!infile.eof()) 
    {
        c=infile.get();     
        if(isalnum(c))
        {
            infile.seekg(-1,ios::cur);
        }

        if(isalnum(c))
        {
            grades stud_temp;

            infile >> stud_temp.mName;
            infile >> stud_temp.mSurname;
            infile >> stud_temp.mAge;
            infile >> stud_temp.mLocation;
            infile >> stud_temp.mMarks;         
            students.push_back(stud_temp);          
        }
    }

【问题讨论】:

  • 我为您的循环提供了更好的解决方案:ideone.com/hMgoP
  • @BenjaminLindley - 太棒了。它有效,但我无法理解逻辑。我试图调试但无法获得逻辑。在你的 for() 代码的哪一部分是测试表达式,这是增量操作。它如何处理每条记录本身开头的空格或中间和结尾的空行。
  • 测试表达式是读取所有数据的部分:inFile &gt;&gt; temp.mName &gt;&gt; temp.mAge etc... -- 它依赖于两个基本事实。 1) istream operator>> 返回流。 2) 可以在布尔上下文中测试流的有效性。所以它会尝试读取数据,如果失败(因为 eof 或其他原因),则条件为假。如果读取成功,则条件为真。 -- 没有增量操作。它通过简单地依靠运算符对空白的正常处理来处理额外的空间,即跳过它。
  • operator&gt;&gt; 首先查找下一个元素,跳过空格。然后当它读取元素时,它会在找到的第一个空格处停止。使用“检查 eof”版本,在读取最后一个元素后,如果文件中仍有空格,则尚未到达 eof,因此您再次进入循环,尝试读取一个元素(失败),但您仍将元素存储在向量中。
  • 然而,在我的版本中,由于读取的成功决定了我们是否会进入循环,读取失败意味着我们甚至没有进入循环,所以元素没有得到放入向量中。

标签: c++ vector


【解决方案1】:

你可以先声明你的向量:

vector<grades> students;

然后读取值,同时推入向量中的元素:

while(!infile.eof()) 
{
    grades student;
    infile >> student.mName;
    infile >> student.mSurname;
    infile >> student.mAge;
    infile >> student.mLocation;
    infile >> student.mMarks;
    students.push_back(student);
}

您不再需要no_of_records,因为记录数将是students.size()

【讨论】:

  • 补充说明:如果你想减少分配次数,请使用students.reserve(initial_amount)(而不是resize)。
  • 您必须确保grades 类具有正确的复制构造函数和赋值运算符。无论如何,这是使用vector 的要求。
  • 如果文件末尾有一个额外的空格或换行符(对于文本文件当然应该允许),您的代码会在向量中添加一个额外的未初始化元素。
  • @Benjamin - 我知道。事实上,我已经在我的实际代码中处理了许多虚假空格(垂直制表符、水平制表符、空格、换行符等)的情况。请。如果有兴趣,请查看编辑后的代码。
猜你喜欢
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 2011-11-22
  • 2023-04-07
相关资源
最近更新 更多