23

How to flush the stdin??

Why is it not working in the following code snippet?

#include <string.h> #include <stdio.h> #include <malloc.h> #include <fcntl.h> int main() { int i = 0, j = 0, sat; char arg[256]; char *argq; argq = malloc(sizeof(char) * 10); printf("Input the line\n"); i = read(0, arg, sizeof(char) * 9); arg[i - 1] = '\0'; fflush(stdin); i = read(0, argq, sizeof(char) * 5); argq[i - 1] = '\0'; puts(arg); puts(argq); return 0; } 

Now if I give the input as 11 characters, only 9 should be read but the remaining two characters in the stdin are not flushed and read again in the argq. Why?

Input: 123 456 789

Output:

123 456 89 

Why am I getting this 89 as the output?

4
  • 20
    Because fflush() is only defined for output streams. Commented Feb 2, 2010 at 20:36
  • 1
    You can always create your own function for discarding input characters. If you name it ignore, then you could be closer to the C++ streams. ;-) Commented Feb 3, 2010 at 0:26
  • See also How to clear input buffer in C? Commented Apr 10, 2022 at 1:21
  • Does this answer your question? How to completely clear stdin and the \n before scanf() Commented Jan 19, 2024 at 11:00

8 Answers 8

46

I believe fflush is only used with output streams.

You might try fpurge or __fpurge on Linux. Note that fpurge is nonstandard and not portable. It may not be available to you.

From a Linux fpurge man page: Usually it is a mistake to want to discard input buffers.

The most portable solution for flushing stdin would probably be something along the lines of the following:

int c; while ((c = getchar()) != '\n' && c != EOF); 
Sign up to request clarification or add additional context in comments.

5 Comments

Nice - didn't know about fpurge()
Or, easier: scanf("%*[^\n]%*c"); You can of course merge this onto the end of your existing scanf format string to discard the remainder of a line after processing part of it with scanf, too..
@R.. perhaps you could explain the provided regex in more detail, even though it's been 5 years. Or provide a link to material that can clarify it.
@Ungeheuer: It's not regex. It's the scanf %[ conversion specifier that should be documented with scanf.
@R..GitHubSTOPHELPINGICE: scanf("%*[^\n]%*c"); will not discard the newline if there is no pending character to match the [^\n] character class, ie: if there is just a newline pending in stdin.
13

From the comp.lang.c FAQ, see:

Comments

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

Is how I'd clear the input buffer.

1 Comment

There might be a potential downside if doing so. Say afterward you want to use fgets read from stdin, which is empty, then you have to firstly type the enter key before the actual typing.
3

How to flush the stdin??

Flushing input streams is invoking Undefined Behavior. Don't try it.

You can only flush output streams.

Comments

2

You are overriding the last element of the input in arg with '\0'. That line should be arg[i]='\0'; instead (after error and boundary checking you are missing.)

Other's already commented of the flushing part.

Comments

2

If you use GLIBC you can just mess with the stdin ptr manually

void flush_stdin(){ unsigned long* tmpstdin = (unsigned long*)stdin; unsigned long* oldbuf = (unsigned long*)*(tmpstdin+4); free((void*)oldbuf); *tmpstdin=(unsigned long)0xfbad2088; tmpstdin+=1; memset(tmpstdin,'\x00',64); } 

Comments

0

You can't clean stdin in Linux without bumping into scenarios that the command will start waiting for input in some cases. The way to solve it is to replace all std::cin with readLineToStdString():

void readLine(char* input , int nMaxLenIncludingTerminatingNull ) { fgets(input, nMaxLenIncludingTerminatingNull , stdin); int nLen = strlen(input); if ( input[nLen-1] == '\n' ) input[nLen-1] = '\0'; } std::string readLineToStdString(int nMaxLenIncludingTerminatingNull) { if ( nMaxLenIncludingTerminatingNull <= 0 ) return ""; char* input = new char[nMaxLenIncludingTerminatingNull]; readLine(input , nMaxLenIncludingTerminatingNull ); string sResult = input; delete[] input; input = NULL; return sResult; } 

This will also allow you to enter spaces in std::cin string.

Comments

-2

In Windows you can use rewind(stdin) fuction.

1 Comment

why don't you post tested code snippet along with your code. Because rewind is not intended to do what OP want achieve.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.