问题
Short version
I want to get rid of excess user input from stdin
but I understand fflush(stdin)
is not recommended. I found this replacement:
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
However, if there is no excess data to remove, this will remove the user's next input. How can I check if there is data to remove from stdin
so I can choose whether or not to use this method of clearing the buffer?
Long version with explanation
I'm making a command-line tool in Obj-C/C.
I understand that declaring char str[SIZE]
syntax allocates SIZE
bytes of memory to str
. I'd like to allocate as little memory as possible to each variable in order to avoid wasting memory.
However, if you use fgets(str,sizeof(str),stdin)
and you enter more than SIZE
bytes of input, fgets
will take SIZE
bytes of your input and store that in str
, leaving all the other data in the buffer. If you call fgets
again, the remaining data will be stored in the variable you pass as fgets
's first variable and essentially skip the prompt completely. I don't want this to happen. A common solution is fflush(stdin)
.
Various internet resources (including SO) state that using fflush(stdin)
is not a good idea because it is "undefined" when you pass an input stream as argument.
I found this replacement on CProgramming.com
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
However, the same source mentions that if there is no excess data in stdin
to get rid of, it will do this with the user's next input, so the second time fgets
is called it might not receive all the data.
How can I check if there is data in stdin
so I can decide whether or not to clear it?
回答1:
If you use fgets to read lines, and you're worried that you might not have read the whole line, remember that if fgets read the whole line the newline character should be the last character in the input buffer.
Example:
char smallBuffer[10];
while (fgets(smallBuffer, sizeof(smallBuffer), stdin) != NULL)
{
if (strlen(smallBuffer) > 0)
{
// Check if we got the whole line
if (smallBuffer[strlen(smallBuffer) - 1] == '\n')
{
// Yes, we got the whole line
}
else
{
// Whole line not read, there is still "excess" input
}
}
}
来源:https://stackoverflow.com/questions/25526856/c-stdin-removing-excess-data