cin.getline y cin.ignore

Iniciado por ricardo2013, 25 Octubre 2012, 13:08 PM

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

ricardo2013

Código (c++) [Seleccionar]

#include <iostream>
#include <limits>

using namespace std;

int main()
{
    char nombre[10] = "";
    int dia = 0;

    cin.getline(nombre, 10, '\n');
    cin.ignore(numeric_limits<int>::max(), '\n');
   
    cout << "dia: ";
    cin >> dia;
    cout << "dia: " << dia << endl;

    return 0;       
}


Compilo y ejecuto:


[tmp]$ g++ a1.cpp -Wall -g -o a1
[tmp]$ ./a1
hola esto es una prueba con una cadena que ocupa mas de 10 caracteres
dia: dia: 0
[tmp]$


¿Por qué no me pide por pantalla el valor de día?

Gracias de antemano

leosansan

Cita de: ricardo2013 en 25 Octubre 2012, 13:08 PM
¿Por qué no me pide por pantalla el valor de día?
Por la "basura" que queda en el buffer, entiéndase excesos de caracteres introducidos que hay que eliminar. Como aficionado te propongo esta solución:
Código (cpp) [Seleccionar]
#include <iostream>
#include <limits>
#include<stdio.h>
using namespace std;

int main()
{
    char nombre[10] = "";
    int dia = 0;
    cin.getline(nombre, 10, '\n');
    cin.ignore(numeric_limits<int>::max(), '\n');
    while (getchar ()!='\n');
    cout << "dia: ";
    getchar ();
    cin >> dia;
    cout << "dia: " << dia << endl;

    return 0;
}

Saludos!.

ricardo2013

Gracias leosansan, pero no soluciona el problema (lo he probado). Según entiendo, cin.getline debería de "eliminar" los datos sobrantes del buffer, pero parece que no funciona. Lo curioso es que el valor que le da a dia es el que tiene por defecto, y no uno cualquier obtenido del buffer. Es como si cin no se ejecutase.

¿A alguien se le ocurre donde puede estar el error?

leosansan

Cita de: ricardo2013 en 25 Octubre 2012, 14:33 PM
Gracias leosansan, pero no soluciona el problema (lo he probado).
CitarEs curioso, a mí entrando más de 10 caracteres si me funciona

ricardo2013

Cita de: leosansan en 25 Octubre 2012, 15:16 PM
Es curioso, a mí entrando más de 10 caracteres si me funciona


[tmp]$ ./test
hola esto es una prueba
dia: 2
dia: 0


Fijate que sigue impriendo 0, el valor que tiene día por defecto.


Yo sigo leyendo y buscando... si cin.getline llega al número máximo de carácteres sin encontrar el delimitador, activa el flag failbit.


Código (c++) [Seleccionar]

#include <iostream>
#include <limits>
using namespace std;

int main()
{
   char nombre[5];
   int dia = 0;
   cin.getline(nombre, 5);
   cin.ignore(numeric_limits<int>::max(), '\n');
   if (cin.fail())
       cout << "fail\n";
   cout << nombre;
   cout << "\ndia: ";
   cin >> dia;
   cout << "el dia es " << dia << endl;
   return 0;
}



[tmp]$ ./dd
hola esto es una prueba
fail
hola
dia: el dia es 0


Fijaros como imprime fail.

He introducido esta línea antes del if(cin.fail())
Código (c++) [Seleccionar]

cin.clear()


Ahora NO imprime el fail pero sigue sin funcionar, el cin no lee nada.

Estoy amargado con esto  :(

ricardo2013

Es así

Código (c++) [Seleccionar]

#include <iostream>
#include <limits>

using namespace std;

int main()
{
    char nombre[10] = "";
    int dia = 0;
    cin.getline(nombre, 10, '\n');
    cin.clear();
    cin.ignore(numeric_limits<int>::max(), '\n');
    cout << "dia: ";
    cin >> dia;
    cout << "dia: " << dia << endl;

    return 0;
}


Primero se desactivan los indicadores de error y después se limpia el buffer con cin.ignore.

Un saludo

rir3760

Puedes ahorrarte la llamada a la función "clear" utilizando, en lugar de "getline", la función miembro "get":
Código (cpp) [Seleccionar]
cin.get(nombre, 10, '\n');
cin.ignore(numeric_limits<int>::max(), '\n');

// ...


Un saludo
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