Как получить пользовательский ввод для строки, а затем int?

У меня есть класс базы данных, который представляет собой массив, который будет содержать несколько объектов. Функция получит от пользователя несколько входных данных, которые включают как строки, так и целые числа

Например:

std::cout << "Enter first name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, first_name);
std::cout << "Enter last name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, last_name);
std::cout << "Enter age: ";
std::cin >> age;

Когда я запускаю код, после того, как я нажимаю клавишу ВВОД после ввода фамилии, он просто начинает новую строку, и мне нужно ввести другой ввод, прежде чем он попросит ввести возраст.

Я слышал, что было плохо смешивать getline и cin, и что лучше использовать один или другой. Что я могу сделать, чтобы сделать эту работу, и что было бы хорошей практикой для продвижения вперед?

Изменить: я добавил в игнорирует, когда я первоначально искал решения, потому что без них код не будет беспокоить ожидание ввода пользователя. Вывод будет "Введите имя: введите фамилию:"

Edit2: РАЗРЕШЕНО. Проблема была в том, что я использовал "cin >>" ранее в своем коде, чтобы пользователь вводил переменную int, и мне нужен был первый оператор cin.ignore, но не другой. Не включил эту часть кода, потому что я не знал, что это повлияло на это. Все еще новичок во всем этом, так что спасибо всем за помощь!

3 ответа

Решение

Согласно документации std::basic_istream::ignore() эта функция работает как неформатированная функция ввода, что означает, что она собирается блокировать и ждать ввода пользователя, если в буфере нечего пропускать.

В вашем случае оба ваших ignore оценки не являются необходимыми, так как std::getline() не оставит символ новой строки в буфере. Так что на самом деле происходит:

std::cout << "Enter first name: ";
/*your first input is skipped by the next ignore line because its going to block until
input is provided since there is nothing to skip in the buffer*/
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
/* the next getline waits for input, reads a line from the buffer and also removes the 
new line character from the buffer*/
std::getline(std::cin, first_name);

std::cout << "Enter last name: ";
/*your second input is skipped by the next ignore line because its going to block until
input is provided since there is nothing to skip in the buffer*/
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
/* the next getline waits for input and this is why it seems you need to provide 
another input before it ask you to enter the age*/
std::getline(std::cin, last_name);

Вы должны удалить ignore отчеты, чтобы сделать эту работу. Вы также можете прочитать Когда и почему мне нужно использовать cin.ignore() в C++

Ваш std::cin::ignore звонки вам не помогают. Они нужны только после ввода, которое не извлекает символ конца строки (>>).

std::string first_name;
std::string last_name;
int age;

std::cout << "Enter first name: ";
std::getline(std::cin, first_name); // end of line is removed

std::cout << "Enter last name: ";
std::getline(std::cin, last_name); // end of line is removed

std::cout << "Enter age: ";
std::cin >> age; // doesn't remove end of line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // this does
// input can proceed as normal

Вам нужно только std::cin::ignore позвонить после std::cin >> age; потому что это не удаляет символ конца строки, тогда как std::getline звонки делают.

Я рекомендую удалить ignore вызовы функций:

std::string name;
std::cout << "Enter name: ";
std::getline(cin, name);
unsigned int age;
std::cout << "Enter age: ";
std::cin >> age;
Другие вопросы по тегам