tipos - bucle infinito en c++
tipos de bucles en programacion (4)
Estoy aprendiendo C ++ y escribiendo pequeños programas a medida que avanzo. El siguiente es uno de esos programas:
// 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;
}
}
Cuando ejecuto este programa y mantengo las entradas en valores absolutos razonablemente pequeños, se comporta como se esperaba. Pero cuando ingreso entradas más grandes, por ejemplo, 10000000000, el programa escupe repetitivamente la misma salida. Algunas combinaciones de entrada causan un comportamiento errático. Por ejemplo:
#: ./int2ch
10
10 -->
10000000000
10 -->
10 -->
10 -->
10 -->
El programa escupe "10 ->" hasta que es asesinado. (Con esta secuencia particular de entradas, la salida del programa cambia la velocidad de forma errática.) También noté que la salida de valores grandes está determinada por la entrada legal anterior así como también por el valor de la entrada ilegal actual.
¿Que esta pasando? (No me importa arreglar el programa, es fácil. Quiero entenderlo).
Dado que está en una máquina de 32 bits, 10000000000 es un número demasiado grande para ser representado por un int. También la conversión de un int a un char solo le dará desde 0..255 o -128..127 dependiendo del compilador.
Sí, Evan Teran ya señaló la mayoría de las cosas. Una cosa que quiero agregar (dado que aún no puedo comentar su comentario :)) es que debes poner la llamada a istream :: clear antes de llamar a istream :: ignore. La razón es que istream :: ignore igualmente se negará a hacer cualquier cosa si la transmisión todavía está en el estado de falla.
Un problema aquí es que un char
tiene un tamaño de un byte y, por lo tanto, solo puede contener un número entre -127 y 128. Un int
por otro lado, normalmente tiene 4 bytes y puede tomar valores mucho más grandes. El segundo problema es que está ingresando un valor que es demasiado grande incluso para un int
.
Básicamente, su secuencia cin
está en un estado de falla y, por lo tanto, regresa inmediatamente cuando intenta leerla. Reescribe tu ejemplo así:
#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
devolverá una referencia a cin
, que puede probar para "bondad" en un condicional. Básicamente, el " while(std::cin >> n)
" dice "mientras aún podía leer con éxito la entrada estándar, haga lo siguiente"
EDITAR: la razón por la que muestra repetidamente el último valor bueno ingresado es porque ese fue el último valor leído con éxito en n, las lecturas fallidas no cambiarán el valor de n
EDITAR: como se señala en un comentario, puede borrar el estado de error e intentar nuevamente algo como esto probablemente funcione y simplemente ignorar los números erróneos:
#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
}
}
}