Если вы введете k
, когда на входе ожидается число.Тогда поток перейдет в состояние ошибки.
Проблема в том, что вы не проверили состояние:
std::cin>>n;
// There could be an error in the line above.
// But you did not check for the error.
Также здесь:
std::cin>>list[i];
// There could be an error in the line above.
// But you did not check for the error.
Попробуйте это:
if (std::cin >> n) {
std::cout << "It worked I got the number: " << n << "\n";
}
else
{
std::cout << "Failed to read a number.\n";
}
Как работает вышеперечисленное.
Что ж, результат operator>>
является ссылкой на поток.Таким образом, он читает значение из потока в n
, но возвращает ссылку на поток.Это позволяет вам делать такие вещи:
std::cin >> n >> x >> y;
После каждого operator>>
вы получаете ссылку на поток для применения к следующему operator>>
, так что вы можете объединять операции чтения вместе.
Когда вы используете поток в логическом контексте (например, тест if или while), он преобразуется в логическое значение в зависимости от его внутреннего состояния.Если внутреннее состояние хорошее std::cin.good()
, то оно вернет true, иначе вернет false.
Таким образом, после завершения ввода operator>>
он преобразуется в bool для if statement
.Если оно в хорошем состоянии, вы знаете, что чтение сработало.Если чтение не удалось, он установил бы внутреннее состояние ошибки и good()
вернул false.
Итак, что произошло в вашем коде.
Что ж, чтение не удалось, и состояние потока было установлено нане удалось.Когда чтение завершается неудачно, предпочтительным поведением является то, что считываемый объект остается неизменным (это то, что происходит для типов POD (стандартных), пользовательских типов, это может быть немного более случайным).
Так что значение n
остается без изменений.
Когда вы объявили n
int n;
Вы не определили начальное значение, поэтому оно имеет неопределенное значение.Что означает, что попытка прочитать это значение - UB.UB это плохо.это означает, что код может делать что угодно (что он и сделал).С практической точки зрения (для большинства систем) это означает, что переменная имеет непознаваемое значение и является тем, что осталось в той ячейке памяти от последней переменной, которая ее использовала.
Для вашего конкретного случая:
Итак, вы сначала набрали 5, а затем k
.
Итак, ваше первое чтение std::cin >> n;
сработало.Следующее чтение std::cin>>list[i];
не удалось.
Это установило плохое состояние потока.Любые последующие чтения ничего не делают (пока вы не сбросите состояние потока на хорошее).Таким образом, вы должны обнаружить и исправить состояние потока.
Каждый последующий раз в цикле std::cin >> list[i]
ничего не будет делать, поскольку поток находится в состоянии ошибки.Это означает, что он сохранит свое первоначальное значение (которое для этого случая определено как ноль 0
).
Опять правильное действие здесь - прочитать и проверить состояние потока.В случае неудачи выполните корректирующее действие:
if (std::cin >> list[i]) {
// Worked
}
else {
std::cerr << "Bad input. Try again\n";
// reset the state of the stream
// before trying to read again.
std::cin.clear();
if (std::cin >> list[i]) {
std::cerr << "You got it correct this time\n";
}
else {
std::cerr << "User not bright enough to use the app aborting\n";
throw std::runtime_error("Failed Bad User");
}
}
Дополнительные примечания
Такое поведение потоков хорошо для чтения пользовательского ввода.Поскольку это позволяет естественный поток для обнаружения и написания кода для пользователя, чтобы исправить проблему.Этот дизайн практически одинаков для всех современных языков с одинаковым шаблоном.
Но это не очень хороший процесс, когда у вас есть машинный ввод (т. Е. Не ожидается никаких ошибок во вводе, и еслипроизошла ошибка, нет способа ее исправить).
Для чтения машинного ввода вы можете настроить поток на выдачу ошибки.Это позволяет вам писать хороший чистый, легко читаемый код, который, когда что-то идет не так (когда они не должны), вызывает исключение, вызывающее корректное завершение приложения (или исключение может быть перехвачено).
std::cin.exceptions(std::ios::badbit); // Fail and Bad