Возникли трудности с получением double после использования getline () в цикле for - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь создать программу, которая получает имена и результаты тестов и помещает их в отдельные векторы. Я использую getline (), чтобы я мог получить как имя, так и фамилию. Однако всякий раз, когда я использую приведенный ниже код, каждое имя после первого теряет свою первую букву. Итак, если для ввода имен использовались Джон Смит, Джейн Смит, Джейкоб Смит и др. c. Программа выводит John Smith, ane Smith, acob Smith, ... Я пытался извлечь cin.ignore (), но затем программа запускается после первой записи. Я также пытался создать отдельные функции для получения имен и оценок, но это тоже не сработало. Любой совет или помощь будут оценены.

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();
}...

1 Ответ

1 голос
/ 14 апреля 2020

Проблема: отсутствует символ

Видите, что cin.ignore(); прямо перед getline(cin, name_list_us[i]);? Угадай, что он делает.

При первом проходе через l oop, который cin.ignore(); съедает символ новой строки, оставленный cin >> num_of_students; Каждый раз, когда через l oop нет символа новой строки, который нужно съесть, поэтому он съедает часть ваши данные.

Решение

Всегда ставьте ignore() s, если вы не можете полностью их избежать, ПОСЛЕ операции, которая оставила мусор, который вы хотите убрать. Если вы поставите ignore() перед другой операцией, рано или поздно вы попадете на эту операцию без мусора в потоке. В этом случае вы нажмете на него раньше.

Далее вы хотите ignore() все, вплоть до новой строки. Все, что пользователь ввел после ввода, который мы хотим, является мусором и должно быть отброшено. В противном случае ignore() вынимает пробел или что-то такое же бесполезное и оставляет новую строку для getline, чтобы отключиться. Я оставлю это старому другу, чтобы объяснил, что вам нужно сделать .

В частности, используйте

cin.ignore(numeric_limits<streamsize>::max(), '\n');

Итак

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'); 
    }
...