Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: MAFUS en 29 Abril 2016, 13:19 PM

Título: TIP: para limpiar el buffer de entrada
Publicado por: MAFUS en 29 Abril 2016, 13:19 PM
Intentando responder a un post y, como siempre pruebo el código de mi respuesta antes, necesitaba de una forma genérica una instrucción para limpiar el buffer de entrada stdin después de adquirir una cadena de entrada mediante fgets.

fgets, según el largo de la cadena introduce saca de stdin el carácter '\n' o no y si se usa while (getchar() != '\n'); sin que haya un carácter de nueva línea en el buffer el programa se detiene y espera a que el usuario introduzca algo. Y eso no queda bien.. Por otra parte controlar a mano si hay o no un carácter de nueva línea es engorroso y ensucia el código.

Llegué a la siguiente solución. Necesita de la librería string.h.


#include <string.h>

#define clrfstr(X) { \
   if(!strchr((X), '\n')) \
       while(getchar() != '\n'); \
}


Esto vacía, o no, stdin dependiendo de si ha la cadena ingresada contiene, o no, el carácter de nueva línea.

El código se debe incluir justo después de fgets o de la función que se haya usado para adquirir la cadena. X es el argumento que representa a la variable cadena adquirida.
Título: Re: TIP: para limpiar el buffer de entrada
Publicado por: HardForo en 29 Abril 2016, 14:54 PM
No se, creo que con esto es suficiente:

#define clrfstr(X) { \
    while(getchar() != '\n'); \
}


Que agrega esa condicion amigo ?
Título: Re: TIP: para limpiar el buffer de entrada
Publicado por: MAFUS en 29 Abril 2016, 16:39 PM
Fragmento de código que hice como respuesta a un juego de mastermind para responder en otro post. Ofrece la funcionalidad de que mira que la entrada de teclado sea efectivamente un número del mismo número de dígitos que la incógnita a buscar, en este programa es un número de 4 dígitos.
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define clrfstr(X) { \
   if(!strchr((X), '\n')) \
       while(getchar() != '\n'); \
}

int validar(char cadena[], size_t sizestr, size_t nelements) {
   int i;
   int ok = 1;
   
   for(i = 0; i<4 && ok; i++)
       ok = isdigit(cadena[i]);
   if(cadena[nelements] != '\n')
       ok = 0;
       
   return ok;
}

int main() {
   const char incognita[] = "1234";
   const int intentos = 10;
   char entrada[sizeof incognita + 1];
   int i;
   int ganador = 0;
   
   for(i = 0; i < intentos && !ganador; ++i) {
       printf("%03i > ", i+1);
       fgets(entrada, sizeof entrada, stdin);
       clrfstr(entrada);
       if(!validar(entrada, sizeof entrada, strlen(incognita)))
           printf("<<< ERROR >>>\n\n");
       else
           ganador = 1;
   }
       
   return 0;
}


Prueba a introducir valores de diferentes cantidades de dígitos, p.ej: 1234, 12, 123456...
ahora borra, o comenta, la línea 6 if(!strchr((X), '\n')) \ y vuelve a probar otra vez. Se ve claramente la diferencia del comportamiento del programa.
Título: Re: TIP: para limpiar el buffer de entrada
Publicado por: NOB2014 en 29 Abril 2016, 18:56 PM
Hola.
Si sirve de algo dejo la manera que yo utilizo para lograr más o menos lo mismo. -

#include <stdio.h>
#include <string.h>

int main( void ){
char a[5], *p = NULL;
size_t ch;

printf( "\n Ingrese una frase...:" );
fgets( a, 5, stdin );
if((p=strchr(a, '\n'))){
*p='\0';
}
else{
while((ch = getchar()) !='\n' && ch!=EOF);
}

printf("\n %s", a);

return 0;
}




(http://i67.tinypic.com/2jac3kk.png)

Saludos.
Título: Re: TIP: para limpiar el buffer de entrada
Publicado por: HardForo en 29 Abril 2016, 19:33 PM
Ya veo.

Ando disperso..... pero el codigo de @Daniel me ayudo a entender lo que comentas @MAFUS  :xD