TIP: para limpiar el buffer de entrada

Iniciado por MAFUS, 29 Abril 2016, 13:19 PM

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

MAFUS

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.

HardForo

No se, creo que con esto es suficiente:

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


Que agrega esa condicion amigo ?
HardForo:  foro de Hardware y programación

Se buscan Mods y colaboradores *

MAFUS

#2
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.

NOB2014

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;
}






Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

HardForo

Ya veo.

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


HardForo:  foro de Hardware y programación

Se buscan Mods y colaboradores *