Reputation: 393
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?
Upvotes: 23
Views: 72633
Reputation: 56
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);
}
Upvotes: 2
Reputation: 293
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.
Upvotes: 0
Reputation:
int c;
while((c = getchar()) != '\n' && c != EOF);
Is how I'd clear the input buffer.
Upvotes: 11
Reputation: 15796
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);
Upvotes: 46
Reputation: 84239
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.
Upvotes: 2
Reputation: 90155
From the comp.lang.c FAQ, see:
Upvotes: 13
Reputation: 111280
How to flush the stdin??
Flushing input streams is invoking Undefined Behavior. Don't try it.
You can only flush output streams.
Upvotes: 3