[C con Clase] vaciar la entrada std

srd4121 en njit.edu srd4121 en njit.edu
Mie Dic 17 12:22:10 CET 2008


Hola Nuria,

Mensaje citado por: Núria Busom Figueres <meteorit666 en hotmail.com>:

> 
> Hola a todos de nuevo!!!
> 
> Sigo con mis problemillas... os cuento. tengo que entrar datos en
> 2vectores distintos y entre uno y el otro tengo que vaciar la entrada.
> He estado buscando por internet i he encontrado varias opciones, pero
> ninguna funciona
> cin.clear(); no hace nada

Esto no sirve para vaciar el búfer de entrada. Esta función miembro sirve para 
despejar errores en el canal producidos por alguna operación anterior que 
afecta el mismo canal de entrada.

> cin.ignore(); me cuelga el programa

Esto no debería producir un error tan extremo. De hecho, esta función miembro 
debería servirte, aunque sería mejor con un parámetro explícito. 
Implícitamente, el primer parámetro es 1; es decir, se ignorará el primer 
carácter en el canal de entrada. El prototipo es el siguiente:

basic_istream &ignore( int nCant = 1, int nDelim = EOF );

Puedes invocarla de esta manera:

cin.ignore( 1024 );

Para ignorar los primeros 1024 caracteres o hasta encontrarse con un fin-de-
fichero.

Si se producen errores, intenta despejar el estado de errores del canal antes 
de invocar esta función. Por ejemplo,

cin.clear();
cin.ignore( 1024 );

> en clase nos han enseñado fflush(); para printf, no se si es correcto
> usarlo aquí, pero tampoco hace nada.

Bueno, dijiste que querías escribir: "fflush(); para stdin".

Quiero dejar esto BIEN CLARO para todo el mundo. La función 'fflush()' NO 
SIRVE PARA CANALES DE ENTRADA. Esta función únicamente sirve para enviar datos 
almacenados en un búfer de canales de salida, como son 'stdout', 'stderr', 
ficheros, etc..

En algunas bibliotecas, sí se define 'fflush()' para 'stdin' para hacer lo que 
quieres: vaciar el canal de entrada. Este comportamiento NO ES ESTÁNDAR, y por 
tanto no todas las bibliotecas tienen por qué aceptarlo.

Otra cosa que quiero aclarar es que no es nada aconsejable mezclar los canales 
de ANSI C como 'stdout', 'stderr', y 'stdin', con los canales de ANSI C++ 
como 'cin', 'cout', 'cerr', etc.. Si piensas usar 'cin' no uses funciones 
para 'stdin'.

> Alguna propuesta??
> 

Tienes dos soluciones principales:

1. Sencillamente usa una cadena temporal para leer y extraer los caracteres 
del canal de entrada. Por ejemplo,

char szCad1[1024], szCad2[1024];
char szAux[1024];

cin >> szCad1;
cin >> szAux;
cin >> szCad1;

También puedes usar 'getline()', si lo prefieres.

Esta solución es la que mencionó Silvio.

2. Ignorar cierta cantidad de caracteres del canal de entrada. Por ejemplo,

cin.ignore( 1024 );


También te puede servir la función miembro 'rdbuf()' para conseguir el búfer 
del canal. Junto con esta función puedes invocar 'in_avail()', para averiguar 
si existen caracteres disponibles para leer en el canal de entrada. Por 
ejemplo,

cin.ignore( cin.rdbuf()->in_avail() );

Aquí ignoraremos tantos caracteres como existen en el canal en esos momentos.

> PD: Programo en C++ i uso cout i cin, que siempre se me olvida!!
> 

Como mencionaste 'cin', ya nos dimos cuenta de que usabas C++ :)


Espero que lo anterior te aclare las dudas. Si aún no funciona, entonces 
sugiero darnos parte del código fuente que tienes escrito.

Steven





Más información sobre la lista de distribución Cconclase