fflush and stdin

A

asit

please fix the bugs...??

#include <stdio.h>

int main()
{
int i;
char j;
printf("Enter any number ...(1 or 2) : ");
scanf("%d",&i);
switch(i)
{
case 1:
printf("Enter any alphabet : ");
fflush(stdin);
scanf("%c",&j);
switch(j)
{
case 'a':
printf("Winners never
quit...");
break;
case 'b':
printf("Quitters never
win...");
break;
}
break;
case 2:
printf("\nFailure is pillar of success..");
}
return 0;
}

It doesn't show the required o/p when run in GCC. Thank You
 
J

jameskuyper

asit wrote:
....
fflush(stdin);

7.19.5.2, descring fflush(stream), says:

"If stream points to an output stream or an update stream in which the
most recent operation was not input, the fflush function causes any
unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined."

Now think carefully about "stdin" and the phrase "output stream".
 
A

asit

asit wrote:

...


7.19.5.2, descring fflush(stream), says:

"If stream points to an output stream or an update stream in which the
most recent operation was not input, the fflush function causes any
unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined."

Now think carefully about "stdin" and the phrase "output stream".


still i can't fix it. please help me.
 
J

jameskuyper

asit said:
still i can't fix it. please help me.

Think! It's not that difficult.

nFurther hints: does 'stdin' qualify as an "output stream"? What does
the above clause say about the results of using fflush() on a stream
which is not an "output stream"? Do you have an output stream in your
program? If so, what is it's name?
 
R

Randy Howard

What does fflush do? Look it up if you don't know. How might it be
relevant to your problem?

-- Richard

Unfortunately, on some platforms fflush(stdin) has implementation
defined behavior that does something sort of like what you might guess,
after you got past it not making sense. :)

The odds are his instructor either doesn't care about it not being
portable, or is not even aware it might be an issue outside of the
platform being used for the course. As such, the op should refer to
either his course notes or documentation for his platform to determine
if in fact his in one of those for which it can be used.
 
L

Lew Pitcher

In addition to the other comments you've received wrt fflush(stdin),
please see below

please fix the bugs...??

#include <stdio.h>

int main()

You aren't taking any arguments in your main(), so how should you have
declared main()? Remember, in a hosted environment, the only two
standard forms are
int main(int argc, char **argv)
and
int main(void)

{
int i;
char j;
printf("Enter any number ...(1 or 2) : ");
scanf("%d",&i);

What will happen if the user doesn't enter a number?
What will this scanf() /not/ read if the user /does/ enter a number?
switch(i)
{
case 1:
printf("Enter any alphabet : ");
fflush(stdin);

See other remarks wrt fflush(stdin)
scanf("%c",&j);

What will happen if the user does not enter a character? (Say, the
user causes end-of-input on stdin, and scanf() encounters the end-of-
file)

What will this scanf() read? Remember that you've previously picked
out /some/ data from the input stream, but the previous scanf() may
not have picked up everything/
switch(j)
{
case 'a':
printf("Winners never
quit...");

What happens when the printf() above executes? What will be printed?
What do you /think/ will be printed?
break;
case 'b':
printf("Quitters never
win...");

What happens when the printf() above executes? What will be printed?
What do you /think/ will be printed?
break;
}
break;
case 2:
printf("\nFailure is pillar of success..");

What happens when the printf() above executes? What will be printed?
What do you /think/ will be printed?
 
A

asit

i have written the program considering user knows every constraint

#include <stdio.h>

int main()
{
int i;
char j;
printf("Enter any number ...(1 or 2) : "); //user will only
enter 1 or 2
scanf("%d",&i); //scanf successfully reads
switch(i)
{
case 1:
printf("Enter any alphabet : ");
fflush(stdin); //any unfetched data from i/p
stream is cleared
scanf("%c",&j); //now what's the problem(in
GCC) ???
switch(j)
{
case 'a':
printf("Winners never
quit...");
break;
case 'b':
printf("Quitters never
win...");
break;
}
break;
case 2:
printf("\nFailure is pillar of success..");
}
return 0;

}
 
H

Harald van Dijk

You aren't taking any arguments in your main(), so how should you have
declared main()? Remember, in a hosted environment, the only two
standard forms are
int main(int argc, char **argv)
and
int main(void)

Or equivalent.

What
int main() { ... }
defines is equivalent to what
int main(void)
defines, even though as declarations, they have a different meaning.

Similarly, what
int main() int argc; char **argv; { ... }
defines is equivalent to what
int main(int argc, char **argv) { ... }
defines, even though again, the former has no prototype.

The standard itself uses the unprototyped int main() form in two
examples. While examples aren't normative, they do help clarify the
intent.
 
L

Lew Pitcher

i have written the program considering user knows every constraint

#include <stdio.h>

int main()
{
int i;
char j;
printf("Enter any number ...(1 or 2) : "); //user will only
enter 1 or 2

No. The user will enter 1 or 2 /and/ at least one other character.
Think about it. Try it yourself. What keys do you hit in order to
enter the data to this prompt? Count them. Which keys are they? What
characters will scanf() see from those keys?
scanf("%d",&i); //scanf successfully reads

If the user entered a number, then scanf() successfully reads that
number.
However, it is the data that the user entered after the number that /
this/ scanf does not read.

switch(i)
{
case 1:
printf("Enter any alphabet : ");
fflush(stdin); //any unfetched data from i/p
stream is cleared

Not according to the standard. Define "unfetched data". Define
"cleared". Now, go read the standard (which has already been quoted to
you) on how fflush() works.

scanf("%c",&j); //now what's the problem(in
GCC) ???

a) fflush(stdin) didn't do what you thought it would do.
b) there is still legitimate data in the buffer that /is not/ the data
that the user entered to your "Enter any alphabet" prompt.
 
J

John Bode

please fix the bugs...??

#include <stdio.h>

int main()

int main(void)
{
int i;
char j;
printf("Enter any number ...(1 or 2) : ");
scanf("%d",&i);

scanf() with the "%d" conversion specifier isn't the greatest tool for
interactive user input. If the user fat-fingers a non-numeric
character, it will be left in the input stream (for example, if the
user types "1w3", scanf() will read and convert the "1", but leave
"w3" in the input stream). Instead of using scanf() for interactive
input, it's better to use fgets() and read everything as a string,
then convert as necessary with other tools. For one thing, it allows
you to recover from bad input more easily, and you can prevent stray
newlines from mucking things up later.
switch(i)
{
case 1:
printf("Enter any alphabet : ");
fflush(stdin);

And here's why you're not seeing what you expect. This doesn't do
what you think it does. Strictly speaking, calling fflush() on an
input stream results in undefined behavior; you cannot rely on it
clearing the input stream. The newline character from the prior
scanf() operation is still in the input stream, so that's the first
thing that the scanf below sees.
 
M

Martin Ambuhl

asit said:
please fix the bugs...??

No, but your subject line points us to these lines:
printf("Enter any alphabet : ");
fflush(stdin);

Which has one logical error and one instance of undefined behavior.
1) Failure to fflush(stdout) after the prompt means (as you discovered)
that input on stdin and output on stdout might not be properly synchronized.
2) fflush is not defined for output streams. It is defined for output
streams and for bidirectional streams on which the last operation was
output. stdin is an input stream and fflush(stdin) has no meaning.
It doesn't show the required o/p when run in GCC. Thank You

No kidding.
 
K

Kelsey Bjarnason

i have written the program considering user knows every constraint

#include <stdio.h>

int main()
{
int i;
char j;
printf("Enter any number ...(1 or 2) : "); //user will only
enter 1 or 2

If I press 1, nothing happens. I have to press something else, don't I,
if I want this to work? But doesn't that, also, end up in the input
buffer? How do you deal with it?
scanf("%d",&i); //scanf successfully reads switch(i)

It *might*. Or the user might accidentally hit something else, such as
'x'.
{
case 1:
printf("Enter any alphabet : ");
fflush(stdin); //any unfetched data from i/p
stream is cleared

Actually, fflush is only defined to work for _output_ streams. stdin is
an _input_ stream.
scanf("%c",&j); //now what's the problem(in
GCC) ???

If I had to guess, I'd say probably the stuff left over from the input of
the number gets read here and as a result, you get unexpected results.
printf("\nFailure is pillar of success..");

On another note, you should either end your outputs with a \n, or flush
the output buffer, as a rule, to ensure the printed text is actually seen.
 
P

pete

asit said:
please fix the bugs...??

#include <stdio.h>

int main()
{
int i;
char j;
printf("Enter any number ...(1 or 2) : ");
scanf("%d",&i);
switch(i)
{
case 1:
printf("Enter any alphabet : ");
fflush(stdin);
scanf("%c",&j);
switch(j)
{
case 'a':
printf("Winners never
quit...");
break;
case 'b':
printf("Quitters never
win...");
break;
}
break;
case 2:
printf("\nFailure is pillar of success..");
}
return 0;
}

It doesn't show the required o/p when run in GCC. Thank You

/* BEGIN new.c */

#include <stdio.h>
#include <stdlib.h>

#define LENGTH 1
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
int rc;
char array[LENGTH + 1];
long i;

printf("Enter a number ...(1 or 2) : ");
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
if (rc == 0) {
array[0] = '\0';
}
if (rc == EOF) {
puts("rc == EOF");
exit(EXIT_FAILURE);
}
i = strtol(array, NULL, 10);
switch (i) {
case 1:
printf("Enter any alphabet : ");
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
if (rc == 0) {
array[0] = '\0';
}
if (rc == EOF) {
puts("rc == EOF");
exit(EXIT_FAILURE);
}
switch (array[0]) {
case 'a':
puts("Winners never quit...");
break;
default:
puts("Quitters never win...");
break;
}
break;
default:
puts("\nFailure is pillar of success..");
break;
}
return 0;
}

/* END new.c */
 
K

Keith Thompson

Harald van Dijk said:
Or equivalent.

What
int main() { ... }
defines is equivalent to what
int main(void)
defines, even though as declarations, they have a different meaning.

I remember a fairly subtle argument that the "int main()" form might
not be legal according to at least one plausible reading of the
standard. I've forgotten the details. In practice, I'd be very
surprised by an implementation that didn't allow both forms -- but
"int main(void)" is better style IMHO.
Similarly, what
int main() int argc; char **argv; { ... }
defines is equivalent to what
int main(int argc, char **argv) { ... }
defines, even though again, the former has no prototype.

I think you meant
int main(argc, argv) int argc; char **argv; { ... }
for the first one.
The standard itself uses the unprototyped int main() form in two
examples. While examples aren't normative, they do help clarify the
intent.

Interesting, I hadn't realized that. The examples are in 6.5.3.4p7
("The sizeof operator") and 6.7.5.3p20 ("Function declarators
(including prototypes)"). In both cases, the use of a non-prototyped
main() is not relevant to the example. I suspect both cases were just
unintentional oversights.
 
A

Army1987

asit said:
fflush(stdin); //any unfetched data from i/p
stream is cleared

Some implementations do define what fflush does on an input stream, but
the C standard doesn't, so that implementations can do whatever they like.
<ot>
For example, on my implementation it sets errno to EBADF and returns EOF.
</ot>
 
R

Randy Howard

Some implementations do define what fflush does on an input stream, but
the C standard doesn't, so that implementations can do whatever they like.
<ot>
For example, on my implementation it sets errno to EBADF and returns EOF.
</ot>

On my platform, a function called fpurge() is provided, which is
documented as follows:

int fpurge(FILE *stream);

The function fpurge() erases any input or output buffered in the given
stream. For output streams this discards any unwritten output. For
input streams this discards any input read from the underlying object
but not yet obtained via getc(3); this includes any text pushed back
via ungetc(3).

The nice thing here is that it makes any use of a platform specific
extension pop out immediately during porting, even if you had not
flagged it previously, and doesn't obscure it behind burying an
extension underneath the implementation of a stadardized function.

I've still never needed to use it however, and likely never will.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top