Esta es la continuacion de la primera parte de la miniguía C++ sobre controles de flujo. En la anterior vimos lo mas basico de estos controles y en este profundizaremos un poco mas en el tema.
cin activa flags que nos indican el estado de la entrada de datos. Ahora vamos a ver un ejemplo en el que realizamos un bucle hasta que se introduce un entero correcto.
//Ejemplo 1 #include <iostream> using namespace std; int main () { int numero = 0; int estado; do { cout << endl << "Introduce un entero válido : "; cin.clear(); //Dejar el estado a goodbit //Ignorar hasta 1024 caract. introducidos hasta encontrar un INTRO (1) //En términos normales, borramos el buffer cin.ignore(1024, '\n'); cin >> numero; estado = cin.rdstate(); //Aquí se requieren conocimientos de aritmética binaria, estamos //comprobando por bits y por eso hacemos un "and logico" para aislar ese bit //Tener en cta. que puede haber otros posibles bits activos //"eofbit" y "batbit" que no usaré aquí. if ((estado & ios::failbit) == ios::failbit) //failbit se activa si no coincide el tipo cout << endl << "A mi no me la das, ¡ESO NO ES UN NÚMERO!" << endl; } while (estado != ios::goodbit); //No hace falta and logico pq goodbit = 0 }
(1) C++ no tiene una forma más elegante de hacer esto, me parece penoso que haya que indicar una longitud y el carácter final en vez de haber creado un simple método por ejemplo "clearbuffer()". Si no indicáramos el '\n' y alguien tecleara "uno dos tres", el bucle se haria 3 veces seguidas, ya que el espacio lo trata como una nueva variable.
Para introducir cadenas de caracteres (más que nada por el tema de los espacios como he comentado arriba), hace falta usar otro método:
//Ejemplo 2 #include <iostream> #include <iomanip> using namespace std; int main() { const int LONG_NOMBRE = 45; char nombre_completo[LONG_NOMBRE]; cout << "Introduce nombre y apellidos "; //Se le puede poner un 3er. parámetro opcional que indica el caracter de //fin de entrada. Por defecto es '\n'. cin.getline( nombre_completo, LONG_NOMBRE ); cout << "hola " << nombre_completo << endl; }
El último ejemplo muestra cómo c++ permite crear un flujo de datos hacia un fichero de la misma forma que hacemos con cout.
Como no vamos a usar la entrada/salida estándar, vamos a usar la unidad fstream en vez de iostream.
//Ejemplo 3 #include <fstream> using namespace std; int main () { ofstream micout ("/tmp/ejemplo3.log"); //flush fuerza la salida del buffer al stream que usemos //es buena práctica usarlo sobretodo en ficheros. micout << "Hola mundo" << endl << flush; micout.close(); }
Lo que os he mostrado aquí, es una pequeña parte del potencial de los flujos de c++. Hay una gran variedad de flags, formatos de salida, gestión de errores, etc. Os invito a que investiguéis por vuestra cuenta.
Comentarios
Ejemplo 1
Tengo un problema en el ejemplo 1, pido la introducción de un caracter, lo introduzco y presiono Intro, sin embargo, no pasa nada, tengo que volver a escribir y volver a presionar intro para que el programa "responda", independientemente de lo que ponga en el segundo valor, siempre toma el valor del primero, me pregunto si habrá forma de solucionar esto.
Gracias.
EDITO: He compilado el ejemplo que has puesto aqui y lo he ejecutado, independientemente de si uso un número o una letra, al principio, siempre imprime lo mismo "A mi no me ladas ¡ESO NO ES UN NUMERO!".
Error en el código
El problema del ejemplo es que el código tiene un error, la verdad, yo probé el ejemplo antes de publicarlo, pero seguramente hice copy&paste de una revisión anterior, sino no me lo explico. Hay 1 linea que están mal
numero = cin.rdstate();
por
estado = cin.rdstate();
Lo que no me fije, es que la primera vez, parece que falla esperando 2 entradas de números. Aún no he sacado qué ocurre.
EDITADO: Sobre la validación del dato con valores tipo numero+letras: Parece ser que si se introduce 12abcdef, C++ *NO* lo interpreta como un error, tan sólo descarta abcdef y toma el valor 12.
LuaDiE: Crea en Lua sin teclear código. Compatible HM7, HMv2, LuaPlayer, LuaDEV y PGE.
Funciona...casi
Ok, ahora ya acepta la entrada de números y distingue entre números y letras, lo único es que tienes que introducir datos 2 veces para que el programa "reaccione".
Saludos
EDITO: Nuevo problema, si implemento lo que pones en tu primer ejemplo en mi segunda variable, ahora si se queda "tonto" totalmente, la unica forma de salir es matando el proceso, ya no basta con introducir cualquier valor y volver a dar enter, se queda completamente tonto. Alguna idea o sugerencia de donde buscar?
2ª variable
No entiendo qué me quieres decir con lo de la segunda variable.
Perdon
Me referia a que quiero que compruebe 2 variables una despues de la otra.
La primera la comprueba después de introducir 2 veces el dato.
La segunda comprobación (La comprobación de la segunda variable introducida) simplemente se queda "tonta" y no responde más.
De cualquier forma, he hecho algo de manera que todo me funciona al 100% , comprueba *3* variables (no he intentado con más) y dice si se trata o no de un numero, aún no entiendo que fue lo que hice, estoy en ello.
Saludos.
no me parece que este bien explicado
Creo que se puede hacer mucho mas al explicar en un tutorial el uso de los cin y cout en c++, y creo que se deverian explicar primero las acciones de estas como funciones ya que de fondo en el codigo es mejor al principio entender como cin y cout imprimen en pantalla o guardan datos a variables, tambien me parece importante desglosar estos codigos de ejemplo por partes para explicar linea por linea mas detalladamente.
No es el objetivo de esta entrega
Ten en cuenta que esta miniguia se enfocan al control de flujo del programa no al funcionamiento de las funciones que mencionas.
Salu2
"El paraíso a mi derecha, el infierno a mi izquierda y el ángel de la muerte tras de mi."
Gracias
gracias por este minitutorial me ha servido por ke estoy viendo c++ en la escuela
MUCHAS GRACIAS