#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::flush;
using std::string;
class Quizdata{
private:
string name;
double total;
int number;
public:
Quizdata()
{
total = 0;
number = 0;
cout << "Enter in name of student: ";
cin.get();
getline(cin, name);
}
// sums up quiz scores for each student
int add_quiz(int score)
{
total+=score;
number++;
}
string get_name()
{
return name;
}
int get_total_score()
{
return total;
}
int get_average_score()
{
return total/number;
}
};
void printresults(Quizdata[], int); // Prototype function
int main()
{
int SIZE, quizzes, score;
cout << "Enter in number of students in class: ";
cin >> SIZE;
cout << "\n";
Quizdata student[SIZE]; // object array created.
cout << "\nHow many quiz scores for each student will be entered? ";
cin >> quizzes;
cout << "\n";
// traversing through object array to get scores of each student
for(int k = 0; k < SIZE; k++)
{
for(int i = 1; i <= quizzes; i++)
{
cout << "Enter in score " << i << " of " << student[k].get_name() << " between 0 and 100: ";
cin >> score;
while(score < 0 || score > 100)
{
cout << "Invalid entry. Please enter again: ";
cin >> score;
}
student[k].add_quiz(score); // send score to add_quiz function to add to 'total'
}
cout << "\n";
}
printresults(student, SIZE); // call to printresults function
return 0;
}
// simply prints the name, total and average of each student
void printresults(Quizdata student[], int SIZE)
{
cout << "\n\n";
for (int i=0; i<SIZE; i++)
{
cout << "Student Name: " << student[i].get_name() << endl;
cout << "Student Total: " << student[i].get_total_score() << endl;
cout << "Student Average: " << student[i].get_average_score() << endl;
cout << "\n\n";
}
}
Here is the output:
Enter in number of students in class: 3
Enter in name of student: George
Enter in name of student: Larry
Enter in name of student: Bernard
How many quiz scores for each student will be entered? 2
Enter in score 1 of George between 0 and 100: 80
Enter in score 2 of George between 0 and 100: 85
Enter in score 1 of arry between 0 and 100: 90
Enter in score 2 of arry between 0 and 100: 92
Enter in score 1 of ernard between 0 and 100: 67
Enter in score 2 of ernard between 0 and 100: 81
Student Name: George
Student Total: 165
Student Average: 82
Student Name: arry
Student Total: 182
Student Average: 91
Student Name: ernard
Student Total: 148
Student Average: 74
Notice how the first letter of 'Larry' and 'Bernard' are not showing. 'George' however is fine. What the hell?
When you call cin.get(); you read one character from cin. That's why the first letter is missing.
The reason why the first letter of the first name is not missing is because when you read the size from cin using >> it leaves the newline character at the end of the line, so the first time get() is called it just removes this newline character and leaves the next line intact.
Using getline removes the whole line, including the newline character which means that the get() that comes after will consume the first character on the next line.
I don't think the get() function belong in the Quizdata constructor. Instead of calling get() before every call to getline you should call it after you have used >>. That way you always leave a fresh line for the next input operation to read from no matter if it happens to be >> or getline.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::flush;
using std::string;
class Quizdata{
private:
string name;
double total;
int number;
public:
Quizdata()
{
total = 0;
number = 0;
cout << "Enter in name of student: ";
//cin.get(); // <-----------------------------------------------------------------------
getline(cin, name);
}
// sums up quiz scores for each student
int add_quiz(int score)
{
total+=score;
number++;
}
string get_name()
{
return name;
}
int get_total_score()
{
return total;
}
int get_average_score()
{
return total/number;
}
};
void printresults(Quizdata[], int); // Prototype function
int main()
{
int SIZE, quizzes, score;
cout << "Enter in number of students in class: ";
cin >> SIZE;
cin.ignore();// <-----------------------------------------------------------------------
cout << "\n";
Quizdata student[SIZE]; // object array created.
cout << "\nHow many quiz scores for each student will be entered? ";
cin >> quizzes;
cout << "\n";
// traversing through object array to get scores of each student
for(int k = 0; k < SIZE; k++)
{
for(int i = 1; i <= quizzes; i++)
{
cout << "Enter in score " << i << " of " << student[k].get_name() << " between 0 and 100: ";
cin >> score;
while(score < 0 || score > 100)
{
cout << "Invalid entry. Please enter again: ";
cin >> score;
}
student[k].add_quiz(score); // send score to add_quiz function to add to 'total'
}
cout << "\n";
}
printresults(student, SIZE); // call to printresults function
return 0;
}
// simply prints the name, total and average of each student
void printresults(Quizdata student[], int SIZE)
{
cout << "\n\n";
for (int i=0; i<SIZE; i++)
{
cout << "Student Name: " << student[i].get_name() << endl;
cout << "Student Total: " << student[i].get_total_score() << endl;
cout << "Student Average: " << student[i].get_average_score() << endl;
cout << "\n\n";
}
}
While not directly affecting the outcome here and as mentioned by someone else above, it is bad programming practice to include input/output functionality (cin, cout, get, getline) in an abstract data class such as the one here. It should all be done elsewhere eg in main() via gets and sets or constructors.
'Bad' is probably a bit discouraging but the point is by doing it the way I suggested your class can be used on any platform, not just a console program.
The 'rule' is a cin.ignore() goes after any cin which immediately precedes a getline()