(Aporte) Diagrama de flujo del operador std::cin>> (std::istream>>)

Iniciado por class_OpenGL, 2 Noviembre 2015, 09:21 AM

0 Miembros y 1 Visitante están viendo este tema.

class_OpenGL

Hola a todos. He visto que muchos de mis amigos y que algunas personas de Internet no comprenden muy bien que es lo que hacen cuando usan std::cin >> variable. Por esto mismo, y pareciendo ser una tontería, he diseñado un pequeño diagrama de flujo para que así vea la gente como funciona. Aquí os lo dejo



Procedo a explicarlo. Lo primero que tenemos que saber es que hay un buffer por ahí que guarda lo que metemos por consola. Entonces, lo primero que hace std::cin>> es comprobar que no haya datos en ese buffer. Si no los hay, entonces procedemos a pedir datos por la consola. Si le damos a enter sin meter nada, entonces se imprimirá un espacio de línea y te pedirá de nuevo que ingreses datos (pues no has ingresado nada), y así hasta que introduzcas algún dato. Entonces, sabiendo que el buffer que maneja std::cin tiene algo, procedemos a comprobar. Lo primero que tenemos que saber es que std::cin recogerá datos de su buffer (que es como una cadena de caracteres) hasta que se encuentre con un espacio (' ') o un salto de línea ('\n'). Entonces, comprobamos si esos datos pueden ser almacenados en la variable que queríamos modificar. Por ejemplo, si la variable es de tipo entero pero "Hola", entonces se determina que no son datos compatibles. En ese caso, a esa variable se le asigna el valor 0 y se establece una bandera de error para que así sepamos que ha habido un error. Date cuenta que si los datos no corresponden, el buffer no se limpia, sino que permanece con los datos introducidos. Pero si los datos concuerdan, entonces se transforman al tipo de variable de entrada y se eliminan esos datos del buffer que maneja std::cin (se eliminan los datos hasta el espacio o salto de línea) y en último lugar se imprime un salto de línea.

Espero que lo hayan entendido y que despeje muchas dudas :D

Ejemplos prácticos de las consecuencias de este diagrama:

Código (cpp) [Seleccionar]
#include <iostream>
#include <limits>

int main() {
   int nValor = 1;
   std::string cString;

   std::cout << "Introduzca un número: ";
   std::cin >> nValor;

   std::cin >> cString;
   
   std::cout << "nValor = " << nValor << std::endl;
   std::cout << "cString = \"" << cString << "\"";

   std::cin.clear();
   std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
   std::cin.get();
   return 0;
}


Si compilamos y ejecutamos este código, obtendremos la siguiente salida (la salida está enmarcada. Lo otro son explicaciones):

Introduzca un número:
Puesto que inicialmente el buffer que maneja std::cin está vacio, entonces el programa se detiene ahí para que introduzcas algo.
Vamos a teclear Hola (que evidentemente no es un entero como se pide) para ver que pasa:

Vamos a comprobar si estáis atentos. ¿Qué debería pasar ahora?

Bien, lo que va a pasar ahora es que std::cin >> cString va a ver que el buffer ya tiene datos guardados (no se han eliminado puesto que se ha producido un error), por lo que el thread no se va a detener como esperaríamos desde un principio, sino que directamente va a asignar esos datos a cString (aquí no hay ningún error, pues "Hola" es un string)

Entonces, una vez pulsado enter al introducir hola, la salida quedaría así:

Introduzca un número: Hola
nValor = 0
cString = "Hola"


Como veis, la variable 'nValor' tiene un valor de 0, pese a que la hemos inicializado como 1. Eso quiere decir que std::cin ha cambiado el valor de esta variable a 0 (tal y como sale en el diagrama).

Bueno, eso es todo. La mejor manera de que lo veáis es que ejecutéis el código por vosotros mismos y experimentéis. Un último apunte: la función std::cin.clear() lo que hace es limpiar la lista de errores producidos, no limpia el buffer!

Gracias por su atención.

Se aceptan sugerencias y/o optimicaciones :D

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

Erecc

Que grande tio, muchas gracias!!! estoy en clase pero en poder le voy a dar un buen ojo XP

class_OpenGL


Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL