бесконечный цикл в c ++ [дублировать]
-
06-07-2019 - |
Вопрос
На этот вопрос уже есть ответ здесь:
Я изучаю 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 -->" до тех пор, пока не будет уничтожена.(С этой конкретной последовательностью входных данных скорость вывода программы изменяется неустойчиво.) Я также заметил, что вывод больших значений определяется предыдущим допустимым вводом, а также значением текущего недопустимого ввода.
Что происходит?(Меня не волнует исправление программы, это просто.Я хочу это понять.)
Решение
В основном ваш 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
, который вы можете проверить на "исправность" в условном.Так что в основном "while(std::cin >> n)
" говорит "пока я все еще могу успешно читать из стандартного ввода, выполните следующее".
Редактировать:причина, по которой он повторно выводит последнее введенное правильное значение, заключается в том, что это было последнее значение, успешно прочитанное в n, неудачные чтения не изменят значение n
Редактировать:как отмечено в комментарии, вы можете очистить состояние ошибки и попробовать еще раз, что-то подобное, вероятно, сработает и просто проигнорирует неверные числа:
#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::игнорировать.Причина в том, что istream::ignore аналогично просто откажется что-либо делать, если поток все еще находится в состоянии сбоя.
Учитывая, что вы находитесь на 32-разрядной машине, 10000000000 - это слишком большое число, чтобы быть представленным int.Также преобразование int в char даст вам значение только от 0 ..255 или -128..127 в зависимости от компилятора.
Одна из проблем здесь заключается в том, что char
имеет размер в один байт и, следовательно, может содержать только число от -127 до 128.Ан int
с другой стороны, обычно он составляет 4 байта и может принимать гораздо большие значения.Вторая проблема заключается в том, что вы вводите значение, которое слишком велико даже для int
.