I have made a class for a student with course and grade, the program keeps asking for a new student until the name given is stop. To store these instances I want to use a vector, but I didn't find any other way to store them than creating an array for the instances first and then pushing them back into the vector. Is it possible to have room for one instance and delete the values stored in Student student after use so it can be reused?
int i=0;
Student student[20];
vector<Student> students;
cout << "Name?" << endl;
getline(cin,student[i].name);
while((student[i].name) != "stop")
{
student[i].addcoursegrade();
students.push_back(student[i]);
i ;
cout << "Name?" << endl;
getline(cin,student[i].name);
if((student[i].name) == "stop")
break;
};
I also use vectors inside the class to store the values for course and grade, since they are also supposed to be growing. The code for the class is here:
class Student {
public:
string name;
void print() {
cout << name ;
for (int i = 0; i < course.size(); i )
cout << " - " << course[i] << " - " << grade[i];
cout<<endl;
}
void addcoursegrade() {
string coursee;
string gradee;
cout << "Course?" << endl;
getline(cin, coursee);
course.push_back(coursee);
while (coursee != "stop") {
cout << "Grade?" << endl;
getline(cin, gradee);
grade.push_back(gradee);
cout << "Course?" << endl;
getline(cin, coursee);
if (coursee != "stop")
course.push_back(coursee);
else if(coursee == "stop")
break;
}
};
private:
vector<string> course;
vector<string> grade;
};
CodePudding user response:
Instead of creating an array then pushing back, simply keep one instance around and reassign it:
Student student;
vector<Student> students;
cout << "Name?" << endl;
getline(cin,student.name);
while((student.name) != "stop")
{
student.addcoursegrade();
// this line copies the student in the vector
students.push_back(student);
// then, reassign the temp student to default values
student = {};
cout << "Name?" << endl;
getline(cin,student.name);
if((student.name) == "stop")
break;
};
CodePudding user response:
A few things bothered me:
- The way your loops were structured, duplicating the
getline
. I prefer a while(true) array with a break when the terminating input appears. - No need for a C-style array.
std::vector
is the way! - separate arrays for course and grade. Instead, I prefer a single record that stores both the course and the grade
- indices in your loops that are only used to access the items within the collection. (Just use a range-based for loop)
- Don't make a
Student
object until you need to. Use local variables for string inputs.
As with anything in C , lots more could be done do to improve it: things like add constructors for your objects, initialize with modern syntax, embrace move semantics, etc. But I'm just making minimal changes.
I'd tackle it like this:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
struct CourseGrade {
string course;
string grade;
};
class Student {
public:
string name;
void print() {
cout << name;
for (auto& courseGrade : courseGrades) {
cout << " - " << courseGrade.course << " - " << courseGrade.grade;
}
cout << endl;
}
void addcoursegrades() {
while (true) {
cout << "Course?" << endl;
string course;
getline(cin, course);
if (course == "stop") break;
cout << "Grade?" << endl;
string grade;
getline(cin, grade);
CourseGrade courseGrade;
courseGrade.course = course;
courseGrade.grade = grade;
courseGrades.push_back(courseGrade);
}
}
private:
vector<CourseGrade> courseGrades;
};
int main() {
vector<Student> students;
while (true) {
cout << "Name?" << endl;
std::string name;
getline(cin, name);
if (name == "stop") break;
Student student;
student.name = name;
student.addcoursegrades();
students.push_back(student);
};
for (auto& student : students) {
student.print();
}
}