Есть несколько проблем, с тем, что вы делаете. Первый , так как Бенуа сказал: вы вызываете cin.ignore()
слишком рано, перед тем, как вывести приглашение. cin.ignore()
будет извлекать ровно один символ из входного потока (если поток не сработал, или он встречает конец файла).
Во-вторых, когда вы цикл (например, потому что пользователь имеет вошел "abc"
), вы звоните cin.ignore()
перед тем сбрасываете ошибку , так что это не-оп. Если пользователь вводит что-либо, кроме , номер, вы зацикливаетесь навсегда, потому что вы застряли на плохом вводе. Вероятно, вы должны поместить cin.clear()
в ветвь if
, которая обрабатывает ошибку. (Конечно, это означает, что вы будете нуждаться в какой-то флаг, чтобы проверить в do...while
, так как ошибка была очищена от времени вы получаете там. Кроме того, вы можете поставить clear
и ignore
в верхней части цикла, но в if
, так что вы только их, если cin.fail()
.)
в-третьих, вы игнорируете ровно один символ. Если пользователь входов "abc"
, это будет цикл четыре раза ("abc"
плюс новая линия ), прежде чем ждать его ввода. Обычным решением является игнорировать через следующий символ новой строки:
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Это должно быть сделано после того, как вы вводите int
(вероятно, неудачу ли вы или нет, но так как вы выход, если вы не» t сбой, на самом деле это не имеет значения, если вы этого не сделаете).
Наконец, две точки по стилю: вездесущий способ interogating ли вход удалось или не лечить поток, как логическое значение:
if (!cin) {
// error...
} else {
// OK...
}
// ...
} while (!cin);
Я не говорю, что это хорошая практика (во многом, я предпочитаю ваш стиль), но так повсеместно, что что-то еще вызывает читателя вашего кода, чтобы начать, и спросить, почему вы сделали что-то другое.
И я бы отделить вход с подсказкой в отдельную функцию, и написать что-то вроде:
template <typename T>
std::istream&
inputWithPrompt(std::istream& source, std::string const& prompt, T& dest)
{
std::cout << prompt;
source >> dest;
return source;
}
int
main()
{
int a;
while (!inputWithPrompt(std::cin, "Enter a number:", a)) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max, '\n');
std::cout << "Invalid input" << std::endl;
}
std::cout << "Number entered is: " << a << std::endl;
return 0;
}
Это кажется намного ровнее мне: петли, пока не удастся, то сделать успешный выход после того, как вы покинете цикл. (Это может быть стоит положить код очистки, то clear
и ignore
в отдельную функции, а также. Если вы ввод с помощью >>
, вам нужно это достаточно часто.)
Вы являетесь слишком щедро с вашим разбрызгиванием 'cin.ignore();'. –