basically in codeblocks for windows before each printf I have "fflush(stdin);" which works. When I copied my code to Linux, it doesn't work, nor does any of the alternatives for "fflush(stdin);" that I've found. No matter which way I seem to do it, the input doesn't seem to be clearing in the buffer or something in my code is incorrect.
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <ctype.h>
int main()
{
char pbuffer[10], qbuffer[10], kbuffer[10];
int p=0, q=0, k=0;
int r, i, Q, count, sum;
char a[3];
a[0]='y';
while(a[0]=='y' || a[0]=='Y')
{
printf("Enter a p value: \n");
fgets(pbuffer, sizeof(pbuffer), stdin);
p = strtol(pbuffer, (char **)NULL, 10);
printf("Enter a q value: \n");
fgets(qbuffer, sizeof(qbuffer), stdin);
q = strtol(qbuffer, (char **)NULL, 10);
printf("Enter a k value: \n");
fgets(kbuffer, sizeof(kbuffer), stdin);
k = strtol(kbuffer, (char **)NULL, 10);
while(p<q+1)
{
Q=p;
sum=0;
count=0;
while(Q>0)
{
count++;
r = Q%10;
sum = sum + pow(r,k);
Q = Q/10;
}
if ( p == sum && i>1 && count==k )
{
printf("%d\n",p);
}
p++;
a[0]='z';
}
while((a[0]!='y') && (a[0]='Y') && (a[0]!='n') && (a[0]!='N'))
{
printf("Would you like to run again? (y/n) ");
fgets(a, sizeof(a), stdin);
}
}
return 0;
}
Drop the need for flushing the input buffer.
OP is on the right track using
fgets()
rather thanscanf()
for input, OP should continue that approach with:Best to not use
scanf()
as it tries to handle user IO and parsing in one shot and does neither that well.Certain present OP's woes stem from
fgets()
afterscanf(" %s", &a);
(which is UB as it should bescanf(" %c", &a);
. Mixingscanf()
withfgets()
typically has the problem that thescanf(" %c", &a);
leaves the Enter or'\n'
in the input buffer obliging the code to want to flsuh the input buffer before the nextfgets()
. Else thatfgets()
gets the stale'\n'
and not a new line of info.By only using
fgets()
for user IO, there need for flushing is negated.Sample
fgets()
wrapperCalling
fflush(stdin)
is not standard, so the behavior is undefined (see this answer for more information).Rather than calling
fflush
onstdin
, you could callscanf
, passing a format string instructing the function to read everything up to and including the newline'\n'
character, like this:The asterisk tells
scanf
to ignore the result.Another problem is calling
scanf
to read a character into variablea
with the format specifier of" %s"
: when the user enters a non-empty string, null terminator creates buffer overrun, causing undefined behavior (char a
is a buffer of one character; string"y"
has two characters -{'y', '\0'}
, with the second character written past the end of the buffer). You should changea
to a buffer that has several characters, and pass that limit toscanf
:I think what you are trying to do is more difficult than it seems.
My interpretation of what you are trying to do is disable type ahead so that if the user types some characters while your program is processing other stuff, they don't appear at the prompt. This is actually quite difficult to do because it is an OS level function.
You could do a non blocking read on the device before printing the prompt until you get EWOULDBLOCK in errno. Or the tcsetattr function family might help. It looks like there is a way to drain input for a file descriptor in there, but it might interact badly with fgets/fscanf
A better idea is not to worry about it at all. Unix users are used to having type ahead and what you want would be unexpected behaviour for them.