I can't clean the keyboard buffer in C

In my code, I request a series of data from the user using the function gets() the problem is that at a certain point in the program when requesting a data with gets() it just jumps to the next request and leaves the variable blank, I've tried cleaning the buffer as follows and it doesn't work:

fflush(stdin);

This is the Code:

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

struct alumnos{
    char nombre[10];
    char dni[20];
    int edad;
};

int main(){
    struct alumnos myalumno[3];
    int i;
    for(i=0;i<=2;i++){
        printf("Ingrese el nombre del alumno %i: ",i+1);
        fflush(stdin);
        gets(myalumno[i].nombre);
        printf("Ingrese el DNI del alumno %i: ",i+1);
        fflush(stdin);
        gets(myalumno[i].dni);
        printf("Ingrese la edad del alumno %i: ",i+1);
        fflush(stdin);
        scanf("%i",&myalumno[i].edad);
    }
}
 3
Author: Carlos A. Gómez, 2016-07-14

2 answers

Taken from here that fflush is only used in output buffers.

Try using fpurge:

int main() {
    struct alumnos myalumno[3];
    int i;
    for(i = 0; i <= 2; i++) {
        printf("Ingrese el nombre del alumno %i: ",i+1);
        fpurge(stdin);
        gets(myalumno[i].nombre);
        printf("Ingrese el DNI del alumno %i: ",i+1);
        fpurge(stdin);
        gets(myalumno[i].dni);
        printf("Ingrese la edad del alumno %i: ",i+1);
        fpurge(stdin);
        scanf("%i",&myalumno[i].edad);
    }
    return 0;
}

Where...

If fflush is given NULL per parameter, it will clean all the output buffers that are active, but fpurge just takes the input buffer and cleans it.

You Should Be careful with using fpurge, it is not a "portable" solution to other platforms, so you should be careful when using it.

Reference: fpurge (En English)

With that should work.

 4
Author: NaCl, 2017-05-23 12:39:23

Since the behavior of fflush is not defined by the standard for input streams, it is only certain that it works for output streams (sending the remaining content of the buffer to the output). Therefore fflush you should not use it.

Is also not recommended to use fpurge as it is not defined in standard C and is also not portable to all platforms (as they have explained in other comments). In fact, on linux it is not available, although the function void __fpurge(FILE *stream) which does the same and is within the GNU standard library (glibc).

The possible solution is to manually write the code that clears the input buffer until it finds a line break. The two options you have are:

char c;
while ((c = getchar()) != '\n' && c != EOF);

And the one that seems better to me:

scanf("%*[^\n]%*c");

In the last option, scanf is first told to ignore (using *) any number of non-blank characters (other than Tab '\t', space ' ' or line break '\n') with the specifier %*[^\n] until it finds a blank character (the line break), in which case it ignores it with the %*c.

The %*c cannot be replaced by \n because in such a case you would be ordering at that point ignore any number of blank characters until you find one that is not, making the function scanf is left waiting for you to enter any non-blank character, which will not be read and will be pending in the buffer input for the next call to scanf.

Note that these solutions are valid if the buffer contains content other than blank characters (' ', '\t' o '\n'). If the buffer is empty, it will wait for keyboard data other than blank characters to be entered (data that it will ignore).

 2
Author: Carlos A. Gómez, 2017-06-28 16:07:00