Cuando se lee un número y después una cadena en C++, se presentan errores. La solución es limpiar el buffer lo cual se puede lograr de dos maneras, con cin.ignore y con fflush.
Al realizar programas de consola en C++, muchas veces necesitamos ingresar datos a través de esta, sin embargo encontramos comportamientos inesperados, como lo vemos en el siguiente código en donde se pide a una persona ingresar su nombre y luego su edad y estos datos se muestran nuevamente en la consola.
PROGRAMA NORMAL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> using namespace std; int main (){ //Declaracion de variables string Nombre; int Edad; cout<<"Ingrese su Nombre: "<<endl; //Pide al usuario datos getline(cin,Nombre); //El usuario ingresa los datos cout<<endl<<"Ingrese su Edad: "<<endl; //Pide al usuario datos cin>>Edad; //El usuario ingresa los datos //El programa imprime los datos cout<<endl<<"Su Nombre es: "<<Nombre<<endl<<"Y su Edad es: "<<Edad<<endl; return 0; } |
El comportamiento es el normal, sin embargo, si nosotros invertimos el orden, es decir, primero ingresamos un numero y después una cadena, el programa a la hora de imprimir no lo haría de la manera adecuada, ya que no permitiría que el usuario ingrese la cadena (en este caso su nombre), como el programa que esta a continuación.
PROGRAMA CON ERROR EN MANEJO DEL BUFFER
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> using namespace std; int main (){ //Declaracion de variables string Nombre; int Edad; cout<<endl<<"Ingrese su Edad: "<<endl; //Pide al usuario datos cin>>Edad; //El usuario ingresa los datos cout<<"Ingrese su Nombre: "<<endl; //Pide al usuario datos getline(cin,Nombre); //El usuario ingresa los datos //El programa imprime los datos cout<<endl<<"Su Nombre es: "<<Nombre<<endl<<"Y su Edad es: "<<Edad<<endl; return 0; } |
Esto ocurre ya que NO hacemos un buen manejo del buffer y limpiarlo antes de ingresar un dato de tipo ‘cadena de caracteres’ (string) o de tipo ‘caracter’ (char), cuando se ingresa por el teclado un valor numérico y se presiona la tecla ‘enter’ esta a su vez ingresa el caracter de fin de cadena ‘endl’ y como los valores numéricos los leemos con el método que cin>> el que extrae del flujo de entrada, lee el valor numérico y descarta el caracter ‘endl’ lo que quiere decir que este permanecerá en el buffer hasta una nueva lectura, y cuando vayamos a leer el datos “nombre” del programa, la función getline() tomará el primer caracter que encuentre, en este caso ‘endl’ y lo que tendremos será una cadena vacía.
SOLUCIÓN PARA LIMPIAR EL BUFFER
Para solucionar hay dos opciones, la primera es limpiando el buffer de entrada con el método cin.ignore () (Opción 1) el cual por defecto borra el primer caracter que encuentra en el buffer (normalmente ‘endl’), a continuación una muestra del código de tal manera que el error quede solucionado.
OPCIÓN 1, Limpiar el buffer con ignore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <iostream> using namespace std; int main (){ //Declaracion de variables string Nombre; int Edad; cout<<endl<<"Ingrese su Edad: "<<endl; //Pide al usuario datos cin>>Edad; //El usuario ingresa los datos cin.ignore(); //<-------Limpiamos el Buffer de tal manera que el programa pueda continuar cout<<"Ingrese su Nombre: "<<endl; //Pide al usuario datos getline(cin,Nombre); //El usuario ingresa los datos //El programa imprime los datos cout<<endl<<"Su Nombre es: "<<Nombre<<endl<<"Y su Edad es: "<<Edad<<endl; return 0; } |
Otro método en el cual podemos solucionar este problema a la hora de leer las cadenas es utilizando la función fflush para limpiar el buffer de entrada de datos (Opción 2), tomaremos el mismo ejemplo y solamente incluiremos la función fflush, para esto primero que nada tendremos que agregar la librería ‘stdlib.h’ para que podamos compilar y correr el programa de manera adecuada, como lo mostraremos en el siguiente código.
OPCIÓN 2, Limpiar el buffer con flush
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <iostream> using namespace std; int main (){ //Declaracion de variables string Nombre; int Edad; cout<<endl<<"Ingrese su Edad: "<<endl; //Pide al usuario datos cin>>Edad; //El usuario ingresa los datos fflush(stdin); //<-------Limpiamos el Buffer de tal manera que el programa pueda continuar cout<<"Ingrese su Nombre: "<<endl; //Pide al usuario datos getline(cin,Nombre); //El usuario ingresa los datos //El programa imprime los datos cout<<endl<<"Su Nombre es: "<<Nombre<<endl<<"Y su Edad es: "<<Edad<<endl; return 0; } |