| Ver tema anterior :: Ver siguiente tema |
| Autor | Mensaje |
|---|
ranqui
Registrado: 02 Sep 2004 Mensajes: 4
| Publicado: 03/09/2004 9:54 am | | | Título: fflush(stdin) en Linux |
| 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 |
|
| Volver arriba | |
 |
alp

Registrado: 12 Abr 2004 Mensajes: 413
| Publicado: 03/09/2004 10:25 am | | | Título: |
| 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. |
|
| Volver arriba | |
 |
ranqui
Registrado: 02 Sep 2004 Mensajes: 4
| Publicado: 04/09/2004 10:15 am | | | Título: |
| 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 |
|
| Volver arriba | |
 |
|
cgomez

Registrado: 09 Ago 2004 Mensajes: 59
| Publicado: 12/09/2004 10:03 am | | | Título: |
| 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: | 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 |
|
| Volver arriba | |
 |
ranqui
Registrado: 02 Sep 2004 Mensajes: 4
| Publicado: 12/09/2004 10:42 am | | | Título: |
| 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 |
|
| Volver arriba | |
 |
ranqui
Registrado: 02 Sep 2004 Mensajes: 4
| Publicado: 28/09/2004 8:49 am | | | Título: Mejor solucion |
| 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 |
|
| Volver arriba | |
 |
|
desorden
Registrado: 15 Dic 2002 Mensajes: 15
| Publicado: 29/09/2004 1:27 pm | | | Título: |
| 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 |
|
| Volver arriba | |
 |
mags_1108
Registrado: 23 Feb 2005 Mensajes: 3
| Publicado: 23/02/2005 4:33 am | | | Título: Una aportación |
| 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. |
|
| Volver arriba | |
 |
anatsu
Registrado: 08 Jun 2007 Mensajes: 1 Ubicación: Iztapalapa (Mexico)
| Publicado: 07/09/2007 12:02 am | | | Título: |
| Otra solucion es poner:
setbuf( stdin, NULL );
antes de las lecturas que fallen. _________________ Tu mejor movimiento es aquel que no dudas en ejecutar. |
|
| Volver arriba | |
 |
|
cheroky
Registrado: 22 Sep 2005 Mensajes: 2566 Ubicación: Valladolid (España)
| Publicado: 07/09/2007 6:52 am | | | Título: |
| | 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: | 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: | 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. _________________ La cuestión no es si hay vida inteligente en otros planetas lejanos. La cuestión es si hay vida inteligente aquí. |
|
| Volver arriba | |
 |
albertomax
Registrado: 03 Abr 2007 Mensajes: 6
| Publicado: 13/09/2007 4:27 pm | | | Título: |
| 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 |
|
| Volver arriba | |
 |
rir3760

Registrado: 01 Oct 2004 Mensajes: 7553 Ubicación: Mexico
| Publicado: 14/09/2007 5:58 am | | | Título: |
| | 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 |
|
| Volver arriba | |
 |
|
Diabliyo
Registrado: 14 Abr 2004 Mensajes: 346 Ubicación: En la Luna
| Publicado: 28/10/2007 9:20 am | | | Título: Re: Mejor solucion |
| | 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() !!
bye bye
bye bye _________________
|
|
| Volver arriba | |
 |
|
|