I would like to know if there is a way, without breaking the C standard, to know if the input buffer stdin
is empty. The objective is to correctly clean said buffer since, by using one of the following two options for it:
char c;
while ((c = getchar()) != '\n' && c != EOF);
either
scanf("%*[^\n]%*c");
in the event that the input buffer was empty, it would remain pending waiting to receive data from the keyboard, being counterproductive because the objective when cleaning the input buffer is simply to empty it (avoiding later on reading remains of previously entered data) in a transparent way, and not request data. In short, clean the buffer if it has content, and if it's empty, do nothing.
Process to clean: once it is known when the input buffer is empty or not, each character of the input is simply read until verifying that it is clean, at which point it would stop reading so as not to be left waiting to request data from the keyboard.
Update : When doing scanf("%d", &n)
there is no problem knowing if there is data left in the buffer because there is always data left in the buffer if %d
there is no white space after the specifier. If there is a blank space, scanf("%d ", &n)
it means that once the number is entered by keyboard, stdin
the subsequent line break is cleared from the buffer, leaving it empty. Therefore, in this case, the status of the buffer would not be known stdin
once the scanf
, since it would be empty or not depending on whether the user enters one or more numbers separated by space.
If after the identifier there is no white space, it means that the line break pressed to enter the data remains in the buffer, always having content in the buffer even when only a number is entered correctly. Therefore, the buffer could be safely flushed afterwards.
In the case of reading character strings with gets
or getchar
, since the line break is read when entering the string, then the way to proceed is the one exposed in @eferion's solution to manually know if there is content in the buffer stdin
after entering the data.
Among the possible solutions I have found so far, they are all outside the C standard:
fpurge
or__fpurge
in glibc: it works perfectly but, in the case of Linux with__fpurge
, it belongs to the GNU standard library.tcflush
determios.h
: This POSIX-defined solution is similar tofpurge
but, instead of flushing the high-level stream bufferFILE *
, it flushes the low-level buffer associated with the file descriptor (fd). Since the ultimate goal is to clear the buffer using functions likescanf
,fwrite
,getchar
, etc, this solution would not work. It would only be valid for the use of functions such asread
those that handle file descriptors.select
deunistd.h
: This POSIX-defined function can be used to tell if the buffer associated with a file descriptor is empty. It works perfectly but, as in the case oftcflush
, only for low-level buffers associated with file descriptors. I implemented a function usingselect
to clear the low-level buffer associated with a file descriptor for data input and it works perfectly (it does the same thing astcflush
), but it does not affect the high-level buffer associated with input streamsFILE *
.One detail you've left out, I don't know if deliberately or unintentionally, is that normally the buffer is deleted after a dirty read... that is, when you know that the buffer has data considered garbage.
If you add that assumption to your equation, the first code you added solves your problem perfectly:
The second system you present, I think I remember, has the drawback that it gets stuck if the first character of the input buffer is just a line break... but right now I don't have an environment where I can test it and confirm it.
Taken from a comment How to act if the user exceeds the maximum allowed?
C is a low-level language with its virtues and its problems... but this should not be one of them:
If we read the data previously with fgets we can determine if there is anything left in the STDIN input buffer. This is as follows, let's see the following code:
If we already have a little experience with fgets we will know that if it still does not reach the character limit, in this case set to 10. Then in the read string it will save the line return with value 0xA. Let's see a few outputs:
We see that if our variable has in its position Strlen - 1 the value 0xA means that there is nothing to read in the buffer.
Otherwise, there is still some data left in the buffer, either pure line return and/or additional text + line return