类的类保持向量

Class holding vector of classes

本文关键字:向量      更新时间:2023-10-16

我正在C++学习OOP,所以我试着练习一下。我想创建一个班级及其学生的"数据库"(使用对象)。我为学生创建了一个课程。每个人都有名字和年龄。

class Ziak {
public:
    Ziak(int,string);
    int getAge() {
        return age;
    }
    string getName() {
        return name;
    }
private:
    int age;
    string name;
};
Ziak::Ziak(int age,string name) {
    this->age=age;
    this->name=name;
}

并且我创建了一个Classroom类,每个类都由它的名字、老师和学生(对象的向量)表示

class Trieda {
public:
    Trieda(string,string);
    void fillStudents() {
        while(1) {
            int age;
            string name;
            cout << "Name: ";
            getline(cin,name);
            cout << "Age: ";
            cin >> age;
            Ziak newStudent(age,name);
            n.push_back(newStudent);
            if(cin.eof()) {
                break;
            }
        }
    }
    string getTeacher() {
        return ucitel;
    }
    string getNamesOfStudents() {
        for(unsigned i = 0; i < n.size(); i++) {
            cout << "hey " << n[i].getName() << endl;
        }
    }
protected:
    vector<Ziak> n;
    string nazov;
    string ucitel;
};
Trieda::Trieda(string nazov,string ucitel) {
    this->nazov = nazov;
    this->ucitel = ucitel;
}

我只是在main中调用它的方法:

int main() {
    Trieda newClass("4A","Ms Foster");
    newClass.fillStudents();
    newClass.getNamesOfStudents();
    return 0;
}

我的问题是输出开始的方法fillStudents()非常好:

Name: // insert name
Age : // insert age

但第二次迭代看起来更糟:

Name:Age: // insert something

第三次迭代是无限循环打印Name:Age:直到世界末日。

我尝试只使用cin >> name而不是getline,例如:

void fillStudents() {
    while(1) {
        int age;
        string name;
        cout << "Name: ";
        cin >> name;
        /*getline(cin,name);*/
        cout << "Age: ";
        cin >> age;
        if(cin.eof()) {
            break;
        } else {
            Ziak newStudent(age,name);
            n.push_back(newStudent);
        }
        cin.clear();
    }
}

它有效。但它的工作原理是这样的:

Name: // insert name
Age : // insert age
// it works till the last one when i press ctrl+Z as eof (currently on windows)
// it outputs Age: Hey + first name ....
Hey name 2 // and so on , then it crashes

这是什么原因造成的?我怀疑这可能是缓冲区未清除的东西,但我尝试了cin.clear(),它也发生了。我怎样才能用getline实现它(我想要全名作为名称输入,例如 John Wicked)。

我正在努力弄清楚,但我只是一个C++初学者,所以我的知识有限,所以我的知识有限。

编辑

我按照评论中发布的问题的建议使用cin.get()修复了它,现在我的函数如下所示:

void fillStudents() {
    while(1) {
        int age;
        string name;
        cout << "Name: ";
        //cin >> name;
        getline(cin,name);
        cout << "Age: ";
        cin >> age;
        if(cin.eof()) {
            break;
        } else {
            if(cin.fail()) {
                cout<< "chyba ";
                break;
            }
            Ziak newStudent(age,name);
            n.push_back(newStudent);
        }
        cin.get();
    }
}

仍然让我不舒服的是cout的输出.它产生这个:

Name: John
Age: 15
Name: Lia
Age: 25
Name: Age: hey John
hey Lia

eofName: Age:仍然被打印出来,我试图cin.eof() while 循环的开头进行测试,但它弄乱了所有输出。如何在不显示eofcout的情况下修改代码?

您需要在输入name和输入age后检查eofCtrl+z^Z))。如果您输入 Ctrl+z for nameeofbit 标志将设置为cin,但直到输出 Age: 后才会被捕获。它不会暂停age输入的原因是:

如果在 [istream] 中到达文件末尾或在输入操作期间发生其他错误,则提取也会停止。 - C++ 参考资料 - 获取线

注意:上面引用中的istream cin在您的代码中。

您的代码应类似于:

// above code removed for brevity
cout << "Name: ";
getline(cin,name);
if(cin.eof()) {
    break;
}
cout << "Age: ";
cin >> age;
if(cin.eof()) {
    break;
} else {
// below code removed for brevity

输出:

Tested on Windows with CodeBlocks and GCC. 
Name: ^Z[Enter]
Process returned 0 (0x0)    execution time : 1.685 s
Press any key to continue.
Name: John
Age: ^Z [Enter]
Process returned 0 (0x0)    execution time : 1.685 s
Press any key to continue.