elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Se pierde el primer cin.getline en un analisis de casos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Se pierde el primer cin.getline en un analisis de casos  (Leído 4,556 veces)
eleon

Desconectado Desconectado

Mensajes: 99


Ver Perfil
Se pierde el primer cin.getline en un analisis de casos
« en: 2 Febrero 2012, 22:41 pm »

Holas:

Tengo un pequeño problemilla y es que dentro de un analisis de casos (switch) no se me ejecuta el primer cin.getline(). Ejemplo:

Código
  1. switch (opcion)
  2.        {
  3.            case 1:
  4.                while (pEA->pSiguiente != 0)
  5.                {
  6.                    pEA = pEA->pSiguiente;
  7.                }
  8.  
  9.                pEA->pSiguiente = new agenda;
  10.                pEA = pEA->pSiguiente;
  11.  
  12.                cout << "Introduzca el nombre: ";
  13.                cin.getline (nuevoNombre, tamNombre); //Este cin.getline() no se ejecuta
  14.                pEA->configurarNombre (&nuevoNombre[0]);
  15.                cout << endl;
  16.  
  17.                cout << "Introduzca el correo: ";
  18.                cin.getline (nuevoCorreo, tamCorreo);
  19.                pEA->configurarCorreo (&nuevoCorreo[0]);
  20.                cout << endl;
  21.  
  22.               ...

He probado quitando la parte de "Introduzca el nombre" para comprobar que no es un error sintáctico y lo que sucede es que no se ejecuta el cin.getline del correo, es decir, el primer cin.getline del "case" se omite. Lo mismo me sucede en "case 2: " etc.

Para corroborarlo he probado a poner antes del "Introduzca el nombre" un cin.getline(cadena_prueba, 30), y entonces si que se ejecuta correctamente el del nombre.

¿Alguno sabe por qué el primero siempre se omite?.

Gracias y saludos.


En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Se pierde el primer cin.getline en un analisis de casos
« Respuesta #1 en: 3 Febrero 2012, 00:40 am »

En la gran mayoría de los casos el comportamiento que mencionas se debe a que, antes de la parte que se "salta", tienes una sentencia que lee un valor de la entrada estándar pero deja el '\n' en el bufer.

Por ejemplo:
Código
  1. string palabra;
  2. char linea[100];
  3.  
  4. // ...
  5.  
  6. cin >> palabra;
  7. cin.getline(linea, 100); // Esto se "salta"

Supongo es eso pero, para estar seguros, lo mejor es revisar el código fuente completo.

Un saludo


En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
eleon

Desconectado Desconectado

Mensajes: 99


Ver Perfil
Re: Se pierde el primer cin.getline en un analisis de casos
« Respuesta #2 en: 3 Febrero 2012, 08:27 am »

Gracias por responder, la única entrada que hay antes es esta:

Código
  1.    while (opcion != 5)
  2.    {
  3.        opcion = 0;
  4.        while (opcion < 1 || opcion > 5)
  5.        {
  6.            F_menu();
  7.            cin >> opcion; //Primera entrada en todo el programa
  8.            cout << endl;
  9.        }
  10.  
  11.        switch (opcion)
  12.        {
  13.            case 1:
  14.                while (pEA->pSiguiente != 0)
  15.                {
  16.                    pEA = pEA->pSiguiente;
  17.                }
  18.  
  19.                pEA->pSiguiente = new agenda;
  20.                pEA = pEA->pSiguiente;
  21.  
  22.                cout << "Introduzca el nombre: ";
  23.                cin.getline (nuevoNombre, tamNombre); // Entrada suprimida
  24.                pEA->configurarNombre (&nuevoNombre[0]);
  25.                cout << endl;
  26.  
  27.                cout << "Introduzca el correo: ";
  28.                cin.getline (nuevoCorreo, tamCorreo);
  29.                pEA->configurarCorreo (&nuevoCorreo[0]);
  30.                cout << endl;
  31. ...

¿Por qué mete un "\n" automáticamente en el buffer?, ¿y cuál sería la solución para evitarlo?.

EDITO: Por si ayuda te pongo el cuerpo del programa hasta donde se produce el error:

Código
  1. int main ()
  2. {
  3.    USHORT opcion;
  4.  
  5.    agenda objeto;
  6.    agenda *pEA = &objeto;
  7.    USHORT numContactos = 0;
  8.  
  9.    char nuevoNombre [tamNombre];
  10.    char nuevoCorreo [tamCorreo];
  11.    ULONG nuevoTelefono = 0;
  12.    ULONG nuevoMovil = 0;
  13.  
  14.    bool encontrado;
  15.    char nombre [tamNombre];
  16.    char correo [tamCorreo];
  17.    char *pNombre = 0;
  18.    char *pCorreo = 0;
  19.    USHORT contador;
  20.  
  21.    int i, j;
  22.  
  23.    while (opcion != 5)
  24.    {
  25.        opcion = 0;
  26.        while (opcion < 1 || opcion > 5)
  27.        {
  28.            F_menu();
  29.            cin >> opcion;
  30.            cout << endl;
  31.        }
  32.  
  33.        switch (opcion)
  34.        {
  35.            case 1:
  36.                while (pEA->pSiguiente != 0)
  37.                {
  38.                    pEA = pEA->pSiguiente;
  39.                }
  40.  
  41.                pEA->pSiguiente = new agenda;
  42.                pEA = pEA->pSiguiente;
  43.  
  44.                cout << "Introduzca el nombre: ";
  45.                cin.getline (nuevoNombre, tamNombre);
  46.                pEA->configurarNombre (&nuevoNombre[0]);
  47.                cout << endl;
  48.  
  49.                cout << "Introduzca el correo: ";
  50.                cin.getline (nuevoCorreo, tamCorreo);
  51.                pEA->configurarCorreo (&nuevoCorreo[0]);
  52.                cout << endl;
  53. ...

Una cosa en la que me acabo de fijar es en cómo inicializo las cadenas en el constructor de la clase; ¿es correcto de esta forma o quizá sea lo que produce el error?:

Código
  1. agenda::agenda()
  2. {
  3.    char nombre = {'\0'};
  4.    char correo = {'\0'};
  5.    telefono = 0;
  6.    movil = 0;
  7.  
  8.    pSiguiente = 0;
  9. }

Un saludo.
« Última modificación: 3 Febrero 2012, 08:37 am por eleon » En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Se pierde el primer cin.getline en un analisis de casos
« Respuesta #3 en: 3 Febrero 2012, 16:31 pm »

El comportamiento es normal. Cuando se ejecuta la sentencia:
Código
  1. cin >> opcion;
Se toman los caracteres necesarios de la entrada estándar pero el '\n' se queda en el bufer.

A continuación se ejecuta:
Código
  1. cin.getline (nuevoNombre, tamNombre);
Y esa función espera "cero o mas caracteres seguidos del avance de linea", como ese ya se encuentra en el bufer se toma y procesa como un linea vacía.

Soluciones hay varias: una es descartar el resto de la linea justo después de la primera sentencia, otra opción es utilizar getline para todas las lecturas junto con la clase "stringstream" para obtener los valores (hay varios ejemplos de ello en la base de datos de los foros).

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
eleon

Desconectado Desconectado

Mensajes: 99


Ver Perfil
Re: Se pierde el primer cin.getline en un analisis de casos
« Respuesta #4 en: 3 Febrero 2012, 22:24 pm »

Gracias por tu tiempo, he optado por usar "cin.ignore(1);" después del cin.

Saludos.
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Se pierde el primer cin.getline en un analisis de casos
« Respuesta #5 en: 4 Febrero 2012, 00:40 am »

En tu caso eso funciona pero (casi) como un castillo de naipes. Para explicarlo mejor compila y ejecuta el programa. Cuando te pida la opción teclea:
Código:
123 {ENTER}
Eso es: 1, 2, 3, un espacio y la tecla {ENTER}.

Es por ello que se considera una mejor opción leer una linea almacenándola en un objeto de la clase "string" y a continuación "extraes" el numero mediante otro objeto de la clase "stringstream".

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Que hago en estos casos?
Ingeniería Inversa
drpanico 2 5,563 Último mensaje 28 Junio 2006, 05:12 am
por CodeName47/GEDZAC
PROBLEMA con la funcion miembro getline() e ignore()
Programación C/C++
.:BlackCoder:. 9 7,847 Último mensaje 27 Julio 2010, 04:29 am
por leogtz
getline()
Programación C/C++
Geek7 3 11,863 Último mensaje 29 Julio 2010, 20:52 pm
por Geek7
[Solucionado]entrar datos con getline utilizar ignore
Programación C/C++
tonilogar 7 6,095 Último mensaje 26 Mayo 2011, 11:02 am
por tonilogar
cin.getline problemas en C++
Programación C/C++
vikour92 0 1,978 Último mensaje 23 Mayo 2012, 19:24 pm
por vikour92
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines