Reputation: 57
I am trying to create a program which obtains names and test scores and places them into separate vectors. I am using getline() so I can get both first and last names. However, whenever I use the below code every name after the first loses its first letter. So, if the input for names was John Smith, Jane Smith, Jacob Smith, etc. The program outputs John Smith, ane Smith, acob Smith,... I tried taking out the cin.ignore()'s but then the program runs through after the first entry. I also tried creating separate functions for obtaining the names and scores, but this did not work either. Any advice or help would be appreciated.
int main() {
string test_taker;
int num_of_students = 0;
cout << "How many students took the exam? ";
cin >> num_of_students;
int starting = 0;
vector <double> score_list_us(num_of_students);
vector <string> name_list_us(num_of_students);
vector<double> score_list_sorted(num_of_students);
vector<string> name_list_sorted(num_of_students);
for (int i =0; i < num_of_students; i++) {
cout << "Student #" << i + 1 << " Name: ";
cin.ignore();
getline(cin, name_list_us[i]);
cout << "Student #" << i + 1 << " Score: ";
cin >> score_list_us[i];
cin.ignore();
}...
Upvotes: 0
Views: 60
Reputation: 33952
See that cin.ignore();
right in front of getline(cin, name_list_us[i]);
? Guess what it does.
On the first pass through the loop that cin.ignore();
eats the newline left by cin >> num_of_students;
Every other time through the loop there is no newline to be eaten, so it eats part of your data.
Always put ignore()
s, if you can't avoid them entirely, AFTER the operation that left the garbage you want gone. If you put ignore()
before another operation, sooner or later you're going to hit that operation without garbage in the stream. In this case you hit it sooner.
Next, you want to ignore()
everything up to and including the newline. Anything the user typed in after the input we want is garbage and should be discarded. Otherwise ignore()
takes out a space character or something equally useless and leaves the newline for getline
to trip over. I'll leave it to an old friend to explain what you need to do.
Specifically, use
cin.ignore(numeric_limits<streamsize>::max(), '\n');
So
int main() {
string test_taker;
int num_of_students = 0;
cout << "How many students took the exam? ";
cin >> num_of_students;
// ignore after
cin.ignore(numeric_limits<streamsize>::max(), '\n');
int starting = 0;
vector <double> score_list_us(num_of_students);
vector <string> name_list_us(num_of_students);
vector<double> score_list_sorted(num_of_students);
vector<string> name_list_sorted(num_of_students);
for (int i =0; i < num_of_students; i++) {
cout << "Student #" << i + 1 << " Name: ";
// not before
getline(cin, name_list_us[i]);
cout << "Student #" << i + 1 << " Score: ";
cin >> score_list_us[i];
// because this guy eats the newlines
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
Upvotes: 1