fflush(stdin) en Linux

Dudas sobre los distintos compiladores C/C++ en Linux
Responder
Mensaje
Autor
Avatar de Usuario
ranqui
Mensajes: 4
Registrado: 02/09/2004 11:00 pm

fflush(stdin) en Linux

#1 Mensaje por ranqui » 03/09/2004 9:54 am

Hola a todos,

Supongo que ya habra salido antes. Estoy con C sobre Linux y no me funciona fflush(stdin), he mirado por la red y en el manual y dice que no limpia el buffer de teclado, sólo fuerza el vaciado de los streams de salida. Mi pregunta es si hay otras funciones de librería que permitan hacer esto u otra solución para que un getchar() no me coja basura y no lea lo que a mi me interesa.
Me he explicado un poco mal pero a ver si alguien lo sabe sin tener que mirarlo

Saludos

Avatar de Usuario
alp
Mensajes: 413
Registrado: 12/04/2004 11:00 pm

#2 Mensaje por alp » 03/09/2004 10:25 am

Hola
¿Que quieres hacer concretamente? Si no utilizas funciones de stream (como scanf(), fgetc(),...) no es necesario fflush()

¿A qué te refieres con que getchar() no coja basura?

Un saludo.

Avatar de Usuario
ranqui
Mensajes: 4
Registrado: 02/09/2004 11:00 pm

#3 Mensaje por ranqui » 04/09/2004 10:15 am

Me refiero a vaciar el buffer de teclado. Por ejemplo si hago dos scanf consecutivos, el segundo se lo salta, supongo que será porque coge el retorno de carro del primero (creo que con getchar() también me pasó). Entonces mi idea es la de poner entre los scanf, un fflush(stdin):

scanf("%c",&a);
............
fflush(stdin);

scanf("%c",&b);

Esto en turboC funciona pero en Linux no. Puede ser que no me haya introducido muy a fondo en el tema de los streams pero, ¿cómo puedo conseguir que se pare el programa en el segundo scanf para leer el dato de forma adecuada sin tener que recurrir a vaciar el stream de entrada (stdin en este caso) a base de leer lo que haya en él hasta que se vacíe.

Gracias y un saludo

Avatar de Usuario
cgomez
Mensajes: 59
Registrado: 09/08/2004 11:00 pm

#4 Mensaje por cgomez » 12/09/2004 10:03 am

Yo para "limpiar" el buffer me valgo de dos artilujios. Para unos casos utilizo getchar () y para otros me valgo de scanf utilizándolo del siguiente modo:

Imagínate que deseas hacer dos scanf seguidos, para leer dos caracteres por ejemplo.

Código: Seleccionar todo

char car1, car2;

printf ("caracter 1: ");
scanf ("%c", &car1);

printf ("caracter 2: ");
scanf ("%*c %c", &car2);

getchar ();
En el segundo scanf es donde puedes encontrar la "peculiaridad". Con ese "%*c" lo que hago es leer el caracter \n que se inserta al pulsar la tecla Enter. Luego utilizo un getchar() al final para leer el segundo '\n' una vez haber pulsado la tecla Enter de nuevo.

Es decir, que cuando necesito hacer varios scanf consecutivamente, opto por introducir el elemento %*c en el formato para ir "comiéndome" los \n leídos a causa de la tecla Enter. Y luego utilizo getchar (); en aquellos casos que no voy a leer datos consecutivamente con scanf o, como en este ejemplo, cuando hago el último scanf.

Yo también he probado la función fflush () en linux y no me ha dado resultados esperados. Seguramente se deba a que en MS-DOS el caracter nueva línea está compiesto por dos caracteres y en UNIX por uno solo. Aunque no estoy nada seguro, así que no me hagas mucho caso.

Saludos
#include "life.h"
Carlos Gómez , ANSI C lover

Avatar de Usuario
ranqui
Mensajes: 4
Registrado: 02/09/2004 11:00 pm

#5 Mensaje por ranqui » 12/09/2004 10:42 am

Todo lo que has comentado me coincide completamente con todo lo que he leido sobre el tema y pienso que tu solución es la más adecuada.

Muchas gracias por la respuesta y un saludo

Avatar de Usuario
ranqui
Mensajes: 4
Registrado: 02/09/2004 11:00 pm

Mejor solucion

#6 Mensaje por ranqui » 28/09/2004 8:49 am

Despues de un tiempo indagando creo que lo mejor para hacer un equivalente a fflush(stdin) es:

void flush_in()
{
int ch;

while( (ch = fgetc(stdin)) != EOF && ch != '\n' ){}
}


A ver que os parece

Saludos

Avatar de Usuario
desorden
Mensajes: 15
Registrado: 15/12/2002 12:00 am

#7 Mensaje por desorden » 29/09/2004 1:27 pm

La solución es buena.

La función fflush sólamente está definida para flujos de datos donde no se produzcan operaciones de entrada. En otro caso, el comportamiento no está definido por el estándar de C. El resultado depende del sistema y del compillador.

Otra posibilidad es usar fgets para la entrada de datos en vez de scanf.
desorden

Avatar de Usuario
mags_1108
Mensajes: 3
Registrado: 23/02/2005 12:00 am

Una aportación

#8 Mensaje por mags_1108 » 23/02/2005 4:33 am

No soy muy entendido del tema, pero me encontre con ese problema mientras hacía una practica de la uni.La putada es que en la uni usamos el visual C y yo en casa (ya que me lo compre he de usarlo) programo en el terminal (Darwin) de mi mac. El terminal(como la consola de MSDOS) segun he leido esta basado en Unix.
Bueno al tema:

El equivalente a fflush(stdin) es fpurge(stdin)..............

A mi se me presentaba el problema cuando hacia:

fgets(...);

- ojo: tenia que poner el fpurge antes de esa sentencia , xq sino se cogía toda la mierda que había en el buffer.

anatsu
Mensajes: 1
Registrado: 08/06/2007 9:37 pm
Ubicación: Iztapalapa (Mexico)

#9 Mensaje por anatsu » 07/09/2007 12:02 am

Otra solucion es poner:

setbuf( stdin, NULL );

antes de las lecturas que fallen.
Tu mejor movimiento es aquel que no dudas en ejecutar.

Avatar de Usuario
cheroky
Mensajes: 2569
Registrado: 22/09/2005 11:00 pm
Ubicación: Valladolid (España)

#10 Mensaje por cheroky » 07/09/2007 6:52 am

cgomez escribió:Yo para "limpiar" el buffer me valgo de dos artilujios. Para unos casos utilizo getchar () y para otros me valgo de scanf utilizándolo del siguiente modo:

Imagínate que deseas hacer dos scanf seguidos, para leer dos caracteres por ejemplo.

Código: Seleccionar todo

char car1, car2;

printf ("caracter 1: ");
scanf ("%c", &car1);

printf ("caracter 2: ");
scanf ("%*c %c", &car2);

getchar ();
En el segundo scanf es donde puedes encontrar la "peculiaridad". Con ese "%*c" lo que hago es leer el caracter \n que se inserta al pulsar la tecla Enter. Luego utilizo un getchar() al final para leer el segundo '\n' una vez haber pulsado la tecla Enter de nuevo.
En realidad deberias hacerlo al reves, primero matcheas el dato y luego lees del buffer.

Código: Seleccionar todo

scanf ("%c %*c", &car1);
scanf ("%c, &car2);
/* */
cgomez escribió:Yo también he probado la función fflush () en linux y no me ha dado resultados esperados. Seguramente se deba a que en MS-DOS el caracter nueva línea está compiesto por dos caracteres y en UNIX por uno solo. Aunque no estoy nada seguro, así que no me hagas mucho caso.
Mas bien se debe a una extension de algunos compiladores, fflush como ya se ha dicho solo esta definido para estreams de entrada, tambien hay que hacer notar que fflush es especifica para volcar los datos de los tampones a fichero.

Una funcion conforme POSIX es la ya comentada por mags_1108, fpurge, si el compilador soporta este estandar.
anatsu escribió:Otra solucion es poner:
setbuf( stdin, NULL );

antes de las lecturas que fallen.
setbuf aunque es estandar no es efectiva en muchos casos y en segun que sistemas.

S2.
Imagen

albertomax
Mensajes: 6
Registrado: 03/04/2007 3:35 pm

#11 Mensaje por albertomax » 13/09/2007 4:27 pm

Normalmente no se ponen dos scanf seguidos por lo que simplemente con que entre las sentencias haya algun printf te bastara para que el segundo scanf no coja el retorno de carro del anterior y si capture lo ultimo que se haya tecleado

un saludo

Avatar de Usuario
rir3760
Mensajes: 7553
Registrado: 01/10/2004 11:00 pm
Ubicación: Mexico

#12 Mensaje por rir3760 » 14/09/2007 5:58 am

albertomax escribió:simplemente con que entre las sentencias haya algun printf te bastara para que el segundo scanf no coja el retorno de carro del anterior
Eso no funcionaria, como ya se indico en el tema se tiene que descartar el resto de la linea mediante un bucle, otra opcion es utilizar el API del SO, por ejemplo en MS Windows se puede utilizar la funcion FlushConsoleInputBuffer.

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

Avatar de Usuario
Diabliyo
Mensajes: 346
Registrado: 14/04/2004 11:00 pm
Ubicación: En la Luna
Contactar:

Re: Mejor solucion

#13 Mensaje por Diabliyo » 28/10/2007 9:20 am

ranqui escribió:Despues de un tiempo indagando creo que lo mejor para hacer un equivalente a fflush(stdin) es:

void flush_in()
{
int ch;

while( (ch = fgetc(stdin)) != EOF && ch != '\n' ){}
}


A ver que os parece

Saludos
La mejor solucion es esa... la he utilizado desde que programo en linux (4 anios ya xD), y simplemente es la mejorsita y se sigue el estandar de unix !!

La otra forma seria como lo menicono rir3760, pero mientras estemos bajo un C que no utilize API's, pues... me imagino que escojeran la del while() :D !!

bye bye

bye bye
Imagen
Imagen

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados