Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

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 a valores absolutos razonablemente pequeños, se comporta como se esperaba. Pero cuando ingreso entradas más grandes, por ejemplo, 10000000000, el programa escupe repetidamente 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 lo maten. (Con esta secuencia particular de entradas, la salida del programa cambia de velocidad de forma errática). También noté que la salida de valores grandes está determinada por la entrada legal anterior, así como por el valor de la entrada ilegal actual.

¿Qué está pasando? (No me importa arreglar el programa, eso es fácil. Quiero entenderlo).

¿Fue útil?

Solución

Básicamente, su secuencia cin está en 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 condicional. Entonces, básicamente, el " while (std :: cin > > n) " dice "aunque todavía podría leer con éxito la entrada estándar, haga lo siguiente"

EDITAR: la razón por la que repetidamente emitió el último valor correcto introducido 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ñaló en un comentario, puede borrar el estado de error e intentar nuevamente algo como esto probablemente funcionaría e ignorar los números incorrectos:

#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
        }
    }
}

Otros consejos

Sí, Evan Teran ya señaló la mayoría de las cosas. Una cosa que quiero agregar (ya que aún no puedo comentar su comentario :)) es que debe poner la llamada a istream :: clear antes la llamada a istream :: ignore. La razón es que istream :: ignore igualmente se negará a hacer cualquier cosa si la transmisión aún está en estado de falla.

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 convertir un int a un char solo te dará de 0..255 o -128..127 dependiendo del compilador.

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 es de 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 .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top