类举行矢量的类

时间:2016-03-02 20:28:01

标签: c++ oop c++11

我正在学习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

Name: Age:之后仍然会打印eof,我试图在while循环的开头放置cin.eof()测试,但它搞砸了所有输出。如何修改代码而不显示cout之后的eof

1 个答案:

答案 0 :(得分:0)

您需要在输入eof后和输入Ctrl+z后检查^Znameage))。如果您为Ctrl+z输入name,则eofbit标记将设置在cin上,但在输出Age:之后才会被捕获。它没有为age输入暂停的原因是:

  

如果在[istream]中到达文件末尾或者在输入操作期间发生了其他错误,则提取也会停止。 - C++ Reference - getline

     

注意:上面引用中的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.