бесконечный цикл в c++
Я изучаю C++ и пишу небольшие программы по ходу дела. Ниже приводится одна из таких программ:
// This program is intended to take any integer and convert to the
// corresponding signed char.
#include <iostream>
int main()
{
signed char sch = 0;
int n = 0;
while(true){
std::cin >> n;
sch = n;
std::cout << n << " --> " << sch << std::endl;
}
}
Когда я запускаю эту программу и сохраняю входные данные на достаточно малых абсолютных значениях, она ведет себя так, как и ожидалось. Но когда я ввожу большие входные данные, например, 10000000000, программа повторяет один и тот же вывод. Некоторые комбинации входных данных вызывают неустойчивое поведение. Например:
#: ./int2ch
10
10 -->
10000000000
10 -->
10 -->
10 -->
10 -->
Программа выплевывает "10 -->", пока ее не убьют. (С этой конкретной последовательностью входы, выход программы изменяют скорость хаотично.) Я также заметил, что выход больших значений определяется предыдущим законным входом, а также значением текущего незаконного входа.
Что происходит? (Я не забочусь о том, чтобы исправить программу, это легко. Я хочу это понять.)
4 ответа:
В основном ваш поток
cin
находится в состоянии сбоя и, таким образом, немедленно возвращается, когда вы пытаетесь прочитать его. Перепишите свой пример следующим образом:#include <iostream> int main() { signed char sch = 0; int n = 0; while(std::cin >> n){ sch = n; std::cout << n << " --> " << sch << std::endl; } }
cin >> n
вернет ссылку наcin
, которую вы можете проверить на "доброкачественность" в условном выражении. Таким образом, в основном the "while(std::cin >> n)
"говорит:" пока я все еще могу успешно читать из стандартного ввода, сделайте следующее "EDIT: причина, по которой он повторно выводит последнее введенное хорошее значение, заключается в том, что это было последнее успешно прочитанное значение в n неудачные чтения не изменят значение n
EDIT: как было отмечено в комментарии, Вы можете очистить состояние ошибки и попробовать снова что-то вроде этого, вероятно, будет работать и просто игнорировать плохие числа:
#include <iostream> #include <climits> int main() { signed char sch = 0; int n = 0; while(true) { if(std::cin >> n) { sch = n; std::cout << n << " --> " << sch << std::endl; } else { std::cin.clear(); // clear error state std::cin.ignore(INT_MAX, '\n'); // ignore this line we couldn't read it } } }
Да, Эван Теран уже указал на большинство вещей. Одна вещь, которую я хочу добавить (так как я не могу прокомментировать его комментарий:)), заключается в том, что вы должны поместить вызов istream::clear Перед вызовом istream::ignore. Причина в том, что istream::ignore подобным образом просто откажется что-либо делать, если поток все еще находится в состоянии fail.
Учитывая, что вы находитесь на 32-разрядной машине, 10000000000-слишком большое число, чтобы быть представленным int. Кроме того, преобразование int в char даст вам только от 0..255 или -128..127 в зависимости от компилятора.
Одна из проблем здесь заключается в том, что
char
имеет размер одного байта и, таким образом, может содержать только число между -127 и 128. С другой стороны,int
обычно составляет 4 байта и может принимать гораздо бОльшие значения. Вторая проблема заключается в том, что вы вводите значение, которое слишком велико даже дляint
.