Can't figure out why scanf does this

N

Neil

Hello

Just to let you know this not homework, I'm learning the language of C
on my own time..

I recently tried to create a escape for user saying
printf ("Do you want to continue? (y or n)");
The scanf statement follows the prompt(printf above) which is the last
statement in the while loop, before the "}"

This scanf statement doesn't work!!
scanf("%c", &answer); //answer is declared as char....OK

When I run the debugger in Turbo C++, it goes rate on by, and doesn't
stop to ask the user to enter a char 'y' or 'n'.......I spent an hour
trying to hault the program at the scanf statement.

What's going on here?

Then I tried this statement.........:)

scanf("\n%c", &answer); //Works!!, but I don't know why?

Can someone tell me? please..

-Neil
Thanks for all your help
 
S

santosh

Neil said:
Hello

Just to let you know this not homework, I'm learning the language of C
on my own time..

I recently tried to create a escape for user saying
printf ("Do you want to continue? (y or n)");
The scanf statement follows the prompt(printf above) which is the last
statement in the while loop, before the "}"

This scanf statement doesn't work!!
scanf("%c", &answer); //answer is declared as char....OK

When I run the debugger in Turbo C++, it goes rate on by, and doesn't
stop to ask the user to enter a char 'y' or 'n'.......I spent an hour
trying to hault the program at the scanf statement.

What's going on here?

It probably has to do with stray input left over in the standard input
stream's internal buffers. These could be ordinary characters or
newlines or whitespace characters. When you call scanf(), it will read
in these characters and return before you want.

Try flushing the buffer with a custom function that uses getc() or
fgetc() or getchar() to read in unwanted input and discard them. Don't
use the fflush() function for input streams. It'll invoke undefined
behaviour.

A better strategy is to use a line oriented input function like fgets()
or the non-portable ggets(), (search this group for posts from
'CBFalconer' with 'ggets' as a keyword), to read in an entire line and
then use functions like sscanf(), strtoXX() family etc. to get what you
want. It's more work upfront, but pays off in the long term, since it's
more robust and flexible than scanf().
 
N

Neil

santosh said:
It probably has to do with stray input left over in the standard input
stream's internal buffers. These could be ordinary characters or
newlines or whitespace characters. When you call scanf(), it will read
in these characters and return before you want.

Try flushing the buffer with a custom function that uses getc() or
fgetc() or getchar() to read in unwanted input and discard them. Don't
use the fflush() function for input streams. It'll invoke undefined
behaviour.

A better strategy is to use a line oriented input function like fgets()
or the non-portable ggets(), (search this group for posts from
'CBFalconer' with 'ggets' as a keyword), to read in an entire line and
then use functions like sscanf(), strtoXX() family etc. to get what you
want. It's more work upfront, but pays off in the long term, since it's
more robust and flexible than scanf().

Thanks for your help, I'll do that...

-Neil.
 
J

Joe Estock

printf ("Do you want to continue? (y or n)\n");

OR

printf ("Do you want to continue? (y or n)");
fflush(stdout);
It probably has to do with stray input left over in the standard input
stream's internal buffers. These could be ordinary characters or
newlines or whitespace characters. When you call scanf(), it will read
in these characters and return before you want.

Not exactly. The OP is omitting the terminating newline in the call to
printf and therefore the buffer is never getting flushed. In the above
scanf call, however, there will be a remaining newline on the stdin
stream and in the next call to scanf (or fgetc, etc) that newline will
be the first character read in.
Try flushing the buffer with a custom function that uses getc() or
fgetc() or getchar() to read in unwanted input and discard them. Don't
use the fflush() function for input streams. It'll invoke undefined
behaviour.

A better strategy is to use a line oriented input function like fgets()
or the non-portable ggets(), (search this group for posts from
'CBFalconer' with 'ggets' as a keyword), to read in an entire line and
then use functions like sscanf(), strtoXX() family etc. to get what you
want. It's more work upfront, but pays off in the long term, since it's
more robust and flexible than scanf().

I completely agree. Even a home-rolled function for this case would suffice.
 
A

Andrew Poelstra

A better strategy is to use a line oriented input function like fgets()
or the non-portable ggets(), (search this group for posts from
'CBFalconer' with 'ggets' as a keyword), to read in an entire line and
then use functions like sscanf(), strtoXX() family etc. to get what you
want. It's more work upfront, but pays off in the long term, since it's
more robust and flexible than scanf().

I don't think that "non-portable" is an appropriate term: the function
is written in Standard C and available wherever you have an Internet
connection (or your friend has an Internet connection and you have a
diskette drive) (or a CD drive, a scanner, a network or a notebook).
 
S

santosh

Andrew said:
I don't think that "non-portable" is an appropriate term: the function
is written in Standard C and available wherever you have an Internet
connection (or your friend has an Internet connection and you have a
diskette drive) (or a CD drive, a scanner, a network or a notebook).

Yes. Apologies, I should've said 'non-standard'.
 
R

Richard Heathfield

santosh said:

It probably has to do with stray input left over in the standard input
stream's internal buffers. These could be ordinary characters or
newlines or whitespace characters. When you call scanf(), it will read
in these characters and return before you want.

Try flushing the buffer

To "flush the buffer" is an output operation, as the description of fflush
makes very clear. I know you're not suggesting that function should be used
(good!); but I think the expression itself is best reserved for uses where
fflush /is/ appropriate, of which this ain't one.

And what's this "stray input", anyway? I don't know about you, but I
consider my time to be sufficiently valuable that I don't waste it typing
stray input into a computer program. If I type the input, I darn well
expect the computer to process it; *I'll* be the judge of whether it's
relevant.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
 
T

trm

Neil said:
I recently tried to create a escape for user saying
printf ("Do you want to continue? (y or n)");
The scanf statement follows the prompt(printf above) which is the
last statement in the while loop, before the "}"

This scanf statement doesn't work!!
scanf("%c", &answer); //answer is declared as char....OK

When I run the debugger in Turbo C++, it goes rate on by, and
doesn't stop to ask the user to enter a char 'y' or 'n'.......I spent
an hour trying to hault the program at the scanf statement.

As someone else already pointed out, the printf() might not be seen
if it isn't terminated by a newline, or followed by an fflush(stdout).
What's going on here?

Then I tried this statement.........:)

scanf("\n%c", &answer); //Works!!, but I don't know why?

Consider also:

scanf(" %c", &answer);
scanf("%1s", &answer);
scanf(" %1[ynYN]", &answer);

Study your documentation for scanf(). When you can explain why
these are equivalent for your example, you'll have a pretty good
understanding of the whole scanf() family, as well as why you don't
usually want to use scanf() for directly reading and parsing input.
 
C

CBFalconer

trm said:
.... snip ...

Consider also:

scanf(" %c", &answer);
scanf("%1s", &answer);
scanf(" %1[ynYN]", &answer);

Study your documentation for scanf(). When you can explain why
these are equivalent for your example, you'll have a pretty good
understanding of the whole scanf() family, as well as why you don't
usually want to use scanf() for directly reading and parsing input.

Those statements are all flawed, in that they fail to check the
return value. A sin with scanf.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top