Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

scanf("%c", &var) behavior!!

205 views
Skip to first unread message

l i z a r d

unread,
Aug 22, 2001, 5:30:01 PM8/22/01
to
I have researched this yet found no answers, so I had to ask on here.

In a program (I will show listing later on), I was trying to get input of
one character.
To achieve that, I used:
scanf("c%", &grade);

unfortunately, that did not work, so I went on and played with it, it only
worked when I changed it to this:

scanf(" %c", &grade); <-- please note the "space" before %c

I really need to know what that is?

Listing linked to underneath (portion concerning the subject matter is
within function gpacomp( ) , please also note that this is unfinished
homework. I do not want someone to help me do it, all I need to know is what
I specified above. )

listing at http://falcon.tp.devry.edu/~oabhari/c/prog.txt

thanks for your help


Des Walker

unread,
Aug 22, 2001, 7:05:20 PM8/22/01
to

l i z a r d <oabh...@home.com> wrote in message
news:tvVg7.22704$MM.14...@news1.mntp1.il.home.com...
Hi,

scanf("%c", &var); /* var is of type char */

will consume one character as you requested.

looking briefly at your code, I see that the instruction is included in
a loop which prints a request for you to enter a value and then makes
the scanf call. This means that to enter a value you are typing at least
two keys. The return key will provide a value that can be read off the
input stream as the line feed character. So with scanf("%c", &var) one
character is read off the stream at a time and the second scanf call
reads the line feed that was left after the first scanf call. It is a
feature of using the %c specifier that white space characters are not
skipped.

Things change when you add a space character because you're now doing
something about white space characters. The space character is a
directive to ignore any white space characters and the %c will match the
first non white space character. So on the first pass through the loop
the line feed is left on the stream as before, but on the second pass
the line feed is discarded (as it is one of the white space character
codes) and you get the value stored that you were expecting.

HTH
Des Walker

Chris Torek

unread,
Aug 22, 2001, 11:59:11 PM8/22/01
to
In article <tvVg7.22704$MM.14...@news1.mntp1.il.home.com>

l i z a r d <oabh...@home.com> writes:
>scanf("c%", &grade);
>
>unfortunately, that did not work, so I went on and played with it, it only
>worked when I changed it to this:
>
>scanf(" %c", &grade); <-- please note the "space" before %c

The scanf() function is a large and complicated beast that usually
does something almost but not entirely unlike what you intended.

In particular, the second scanf() call contains two "formatting
directives", namely " " and "%c". The %c directive is fairly
straightforward: it reads a single character from the input stream
-- in this case stdin -- and assigns that character through the
supplied pointer (&grade, pointing to the variable "grade").

The %c directive can never fail with a matching failure, only with
an input failure. This occurs only when fgetc() would have returned
EOF.

The first directive, however, is not at all straightforward. This
whitespace character (" ") tells scanf() to read from the input
stream, and keep on reading, until it the next input character is
something other than white-space. But newlines ('\n') are white
space, by definition -- so this scanf() call begins by skipping
over as many blank lines as the user is willing to enter!

In other words, if you print a prompt:

printf("please enter something: ");
fflush(stdout);

and then use scanf() with a whitespace directive (including space,
tab, and newline), and the user just presses RETURN (or ENTER or
whatever), the computer will simply sit there waiting. There will
be no re-prompt to "enter something".

The " " directive never fails, because "no white space" works just
as well as "three million empty lines".

Chances are that the reason adding the blank to the scanf() made
your code "do what you wanted" (sometimes...) is that you used
scanf() earlier. The earlier scanf() then laid a trap for later
input, because scanf() tends to do something almost but not entirely
unlike what you intended. The best course of action is to stop
using scanf() entirely, as noted in the FAQ. If you use functions
that do *not* lay traps for the unwary -- that means avoiding
both scanf() and gets(), but you can use sscanf() and fgets() --
you will not have to navigate carefully around your own land mines.
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
El Cerrito, CA, USA Domain: to...@bsdi.com +1 510 234 3167
http://claw.eng.bsdi.com/torek/ (not always up) I report spam to abuse@.

Mohit Sindhwani

unread,
Aug 23, 2001, 1:13:47 AM8/23/01
to
Hi. Number of small things to point you in the correct direction.

1. Read a book on C. Any book. Please, I refuse to accept that
anything would suggest that you can use 'scanf("c%", &grade);' as a
valid construct to getting an input from a user. I'm not exactly a C
guru, but basic common sense (and perhaps the first chapter on I/O)
would set that issue straight. I'm sorry I don't share the same
enthusiasm that you do when you point out (almost as a discovery) that
'%c' works.

2. Now, back to the problem. It stems from the way that scanf()
behaves and from the fact that C does input from a buffer. (I think
that's why they use the term buffered I/O for C). Basically, scanf()
checks the input buffer and gets back whatever is there. It waits
only if the buffer is enmpty. In this case, it gets whatever you type
in ONLY after the 'enter' key is hit. It takes that and reads
whatever you ask of it from that and leaves the rest as it is.

If you do an input somewhere (let's assume that this is the first time
you do an input) such as:

/**/ scanf("%c",&a);

and in response you type in at the keyboard
M (followed by enter)
The buffer has 2chars in it:
M(enter)

{{ I'm using (enter) for the newline char in this mail }}

When you do a read from here, the scanf will read the 'M' into the
variable leaving the (enter) in the buffer. If, after this, you do
another scanf() asking for a character, it goes to the buffer and
finds an (enter) there. It reads this into the character variable you
ask it to.

It doesn't wait for an input basically because there is a character in
the buffer already. It just picks up that character and returns.

Try this piece of code:

/* ----------------- */
#include <stdio.h>

int main (void) {
char a;

scanf ("%c", &a); /* 1 */
scanf ("%c", &a); /* 2 */
printf ("\n--%c--\n--",a);

return 0;
}
/* ----------------- */

You'll see the exact behavior defined above. To understand better,
when you start, enter 2 characters before you press enter. You will
see that the printf will display the second character since that is in
the buffer after the first scanf() attempt.

Finally, the question arises as to why the " %c" works. This works
because the ' ' in the input format specifier indicates to C that you
want it to skip all the white space characters in the input buffer
prior to reading the data. In this case, if your buffer was:
M(enter)
-- first scanf() reads the 'M'--
you are left with:
(enter)
-- the second scanf() will ignore the enter: that empties the buffer,
so it waits --

That explains why it works for you. To see the effect of the ' %c'
better change the line remarkes as '2' in the code above to:
scanf (" %c",&a); /* 2 - modified */

Then, try this:
a. In response to the first scanf() enter: 12(enter)
You'll see that the second scanf reads '2' (becos it's in the buffer)

b. In response to the first scanf() enter: 1(enter)
In response to the second scanf() enter: 2(enter)
This works as you want it to...

c. In response to the first scanf() enter: 1(enter)
In response to the second scanf() enter: (space)(space)2(enter)
This gets back the 2 as the (space) is ignored as white space.

d. Finally, in response to the first scanf() enter: 1(space)2(enter)
You'll see that this does not stop for you to enter data. The first
scanf() reads the '1'... the second skips the (space) and reads the
'2'

I know this explanation has got a bit wordy. But, I hope that it
clears the doubt you have.

Regards
Mohit.


"l i z a r d" <oabh...@home.com> wrote in message news:<tvVg7.22704$MM.14...@news1.mntp1.il.home.com>...

Richard Heathfield

unread,
Aug 23, 2001, 2:58:48 AM8/23/01
to
Mohit Sindhwani wrote:
>
> Hi. Number of small things to point you in the correct direction.
>
> 1. Read a book on C. Any book. Please, I refuse to accept that
> anything would suggest that you can use 'scanf("c%", &grade);' as a
> valid construct to getting an input from a user.

Ah, but Herbert Schildt does exactly that. C-TCR(2e), p221.

But no, that is *not* a recommendation to buy the book!

<snip>

--
Richard Heathfield : bin...@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton


CBFalconer

unread,
Aug 23, 2001, 4:54:15 PM8/23/01
to
Mohit Sindhwani wrote:
>
> Hi. Number of small things to point you in the correct direction.
>
> 1. Read a book on C. Any book. Please, I refuse to accept that
... snip ...

Exactly. You entered this as a reply to Chris Toreks message, and
I am sure he has read many books on C, and knows what he is
talking about. ALWAYS READ Chris's postings. It is the law here.

Also, you top-posted, so the whole thing makes no sense. You
failed to snip non-relevant portions.

http://www.netmeister.org/news/learn2quote.html
http://fmf.fwn.rug.nl/~anton/topposting.html
http://www.malibutelecom.fi/yucca/usenet/brox.html

--
Chuck F (cbfal...@yahoo.com) (cbfal...@XXXXworldnet.att.net)
(Remove "XXXX" from reply address. yahoo works unmodified)
mailto:u...@ftc.gov (for spambots to harvest)


Mohit Sindhwani

unread,
Aug 23, 2001, 11:41:05 PM8/23/01
to
CBFalconer <cbfal...@yahoo.com> wrote in message news:<3B855339...@yahoo.com>...

> Mohit Sindhwani wrote:
> >
> > Hi. Number of small things to point you in the correct direction.
> >
> > 1. Read a book on C. Any book. Please, I refuse to accept that
> ... snip ...
>
> Exactly. You entered this as a reply to Chris Toreks message, and
> I am sure he has read many books on C, and knows what he is
> talking about. ALWAYS READ Chris's postings. It is the law here.

I would never never ask Chris to read a book on C :-) I have
discovered that since I joined the group. My message was actually a
response to the original poster who used "c%" and the recommendation
was to read a book since NO book on C would recommend that instead of
"%c". Part of the problem arose from the fact that I use Google
Groups and the messages show up much later. When I responded there
was only 1 response to the original poster. I didn't even know that
Chris had responded (his response required no further clarification,
really)

I do READ all of Chris' postings (at least the new ones).. I am a law
abiding citizen. :-)


> Also, you top-posted, so the whole thing makes no sense. You
> failed to snip non-relevant portions.

On these accounts, I plead guilty. Bad habits that I am going to make
a conscious effort to change. Apologies to the group for that.

Sorry for the confusion.

To better days ahead,
Cheers,
Mohit.

Dann Corbit

unread,
Aug 23, 2001, 11:54:58 PM8/23/01
to
"Mohit Sindhwani" <emsin...@yahoo.com.sg> wrote in message
news:fe83e076.01082...@posting.google.com...


They are sure to follow.

To all new posters:
See what Mohit did up above? This is a clear sign of someone who is going
to learn a lot very rapidly. Notice the willingness to make adjustments.
Notice the lack of taking offense.

This post is so beautiful, it almost needs to be framed.
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm


Zoran Cutura

unread,
Aug 24, 2001, 1:11:45 AM8/24/01
to
Once upon a while "CBFalconer" <cbfal...@yahoo.com> wrote:

> Mohit Sindhwani wrote:
>>
>> Hi. Number of small things to point you in the correct direction.
>>
>> 1. Read a book on C. Any book. Please, I refuse to accept that
> ... snip ...
>
> Exactly. You entered this as a reply to Chris Toreks message, and
> I am sure he has read many books on C, and knows what he is
> talking about. ALWAYS READ Chris's postings. It is the law here.
>

It's doesn't appear as a reply to Chris in my Newsreader.
Actually looking at the headers the only refenrence is

References: <tvVg7.22704$MM.14...@news1.mntp1.il.home.com>

which appears to be the OP's Message:

Message-Id: <tvVg7.22704$MM.14...@news1.mntp1.il.home.com>

so, it ought to be a bug in your Newsreader (believe it or not
Mozilla has bugs).


> Also, you top-posted, so the whole thing makes no sense. You
> failed to snip non-relevant portions.

Hmm, that is a thing why he should be tared and feathered! :-)

--
Z (Zoran....@daimlerchrysler.com)
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond

Richard Heathfield

unread,
Aug 24, 2001, 1:38:06 AM8/24/01
to
Zoran Cutura wrote:
>
> Once upon a while "CBFalconer" <cbfal...@yahoo.com> wrote:
>
> > Mohit Sindhwani wrote:
> >>
> >> Hi. Number of small things to point you in the correct direction.
> >>
> >> 1. Read a book on C. Any book. Please, I refuse to accept that
> > ... snip ...
> >
> > Exactly. You entered this as a reply to Chris Toreks message, and
> > I am sure he has read many books on C, and knows what he is
> > talking about. ALWAYS READ Chris's postings. It is the law here.
> >
>
> It's doesn't appear as a reply to Chris in my Newsreader.
> Actually looking at the headers the only refenrence is
>
> References: <tvVg7.22704$MM.14...@news1.mntp1.il.home.com>
>
> which appears to be the OP's Message:
>
> Message-Id: <tvVg7.22704$MM.14...@news1.mntp1.il.home.com>
>
> so, it ought to be a bug in your Newsreader (believe it or not
> Mozilla has bugs).

I don't think so. I think it means his (Chuck's) newsfeed is not getting
100% of the posts. I've noticed that, if A posts, and B and C both reply
directly to A, but my news server doesn't have A's article, then C's
article is shown as a "child" of B's article in my newsreader, in order
to avoid wrongly suggesting there are two threads here. I don't think
that's a bug. I think it's one way to solve a problem. The other way is
*not* to make C a child of B, in which case they would show up as two
different threads and some people would complain that *that* was a bug.

> > Also, you top-posted, so the whole thing makes no sense. You
> > failed to snip non-relevant portions.
>
> Hmm, that is a thing why he should be tared and feathered! :-)

Again, I must disagree. Given that he has now apologised for something
that is clearly not even his fault (and also some things that are), I
think he should instead be tortured by being forced to sit in a
comfortable armchair whilst someone brings him fiendishly tasty coffee
and biscuits. THAT will teach him to mess with comp.lang.c! HA!

HA!

HAHAHAHAHAHAHAHA!!!!!

(Read Pratchett's "Maskerade" for an explanation of the excessive
exclamation marks.)

Zoran Cutura

unread,
Aug 24, 2001, 3:12:00 AM8/24/01
to
Once upon a while "Richard Heathfield" <bin...@eton.powernet.co.uk> wrote:

> Zoran Cutura wrote:
....

> I don't think so. I think it means his (Chuck's) newsfeed is not getting
> 100% of the posts. I've noticed that, if A posts, and B and C both reply
> directly to A, but my news server doesn't have A's article, then C's
> article is shown as a "child" of B's article in my newsreader, in order
> to avoid wrongly suggesting there are two threads here. I don't think
> that's a bug. I think it's one way to solve a problem. The other way is
> *not* to make C a child of B, in which case they would show up as two
> different threads and some people would complain that *that* was a bug.
>

This happens with my newsreader too. And I think there would be
more sollutions to the problem than the two you mention. As
there are articles listed in the References:-header-entry that
can't be found locally it would be a good idea if a newsreader
would show referenced articles in the thread but mark 'em as
unretrieved for example. And I bet there are even better
sollutions. So still I find the mentioned behavior to be buggy
rather than helpful.

I shall write my own newsreader one lonely day. :)


>> > Also, you top-posted, so the whole thing makes no sense. You
>> > failed to snip non-relevant portions.
>>
>> Hmm, that is a thing why he should be tared and feathered! :-)
>
> Again, I must disagree. Given that he has now apologised for something
> that is clearly not even his fault (and also some things that are), I
> think he should instead be tortured by being forced to sit in a
> comfortable armchair whilst someone brings him fiendishly tasty coffee
> and biscuits.

It appears, that his appolgy appeared in my ISP's INN-service
right after I posted my reply to Chuck, so I have to admit
that the punishment must not be to hard. Anyhow, don't you think
your act would sort of overdo it a bit?

> THAT will teach him to mess with comp.lang.c! HA!
>
> HA!
>
> HAHAHAHAHAHAHAHA!!!!!
>
> (Read Pratchett's "Maskerade" for an explanation of the excessive
> exclamation marks.)
>

I summon the wast power of science fiction. Will I ever be able
to read all books I want to? Can you give me a short resume
about the exclamation marks?

Jirka Klaue

unread,
Aug 24, 2001, 6:17:27 AM8/24/01
to

Zoran Cutura wrote:

> Once upon a while "Richard Heathfield" <bin...@eton.powernet.co.uk> wrote:

[...]

>>THAT will teach him to mess with comp.lang.c! HA!
>>
>>HA!
>>
>>HAHAHAHAHAHAHAHA!!!!!
>>
>>(Read Pratchett's "Maskerade" for an explanation of the excessive
>>exclamation marks.)
>>
>>
>
> I summon the wast power of science fiction. Will I ever be able
> to read all books I want to? Can you give me a short resume
> about the exclamation marks?


"Five exclamation marks, the sure sign of an insane mind."

-- Terry Pratchett

Jirka

Jirka Klaue

unread,
Aug 24, 2001, 6:28:07 AM8/24/01
to
Zoran Cutura wrote:

> Once upon a while "Richard Heathfield" <bin...@eton.powernet.co.uk> wrote:
>

[...]

>
>>THAT will teach him to mess with comp.lang.c! HA!
>>
>>HA!
>>
>>HAHAHAHAHAHAHAHA!!!!!
>>
>>(Read Pratchett's "Maskerade" for an explanation of the excessive
>>exclamation marks.)
>>
>
> I summon the wast power of science fiction. Will I ever be able
> to read all books I want to? Can you give me a short resume
> about the exclamation marks?

>

Or was it that quote, Richard meant ?

"'And all those exclamation marks, you notice? Five? A sure sign of
someone who wears his underpants on his head.'"

I don't hope so. Not that it would influence his C skills, but ...

Jirka

CBFalconer

unread,
Aug 24, 2001, 9:58:38 AM8/24/01
to
Zoran Cutura wrote:
>
> Once upon a while "CBFalconer" <cbfal...@yahoo.com> wrote:
>
> > Mohit Sindhwani wrote:
> >>
> >> Hi. Number of small things to point you in the correct direction.
> >>
> >> 1. Read a book on C. Any book. Please, I refuse to accept that
> > ... snip ...
> >
> > Exactly. You entered this as a reply to Chris Toreks message, and
> > I am sure he has read many books on C, and knows what he is
> > talking about. ALWAYS READ Chris's postings. It is the law here.
>
> It's doesn't appear as a reply to Chris in my Newsreader.
> Actually looking at the headers the only refenrence is
>
> References: <tvVg7.22704$MM.14...@news1.mntp1.il.home.com>
>
> which appears to be the OP's Message:

It appeared here linked to Chris' message, and containing (after
the top-posting) Chris' actual message quoted. So I don't think
Netscape fouled anything here.

Zoran Cutura

unread,
Aug 24, 2001, 10:34:29 AM8/24/01
to
Once upon a while "CBFalconer" <cbfal...@yahoo.com> wrote:

...


> It appeared here linked to Chris' message, and containing (after
> the top-posting) Chris' actual message quoted. So I don't think
> Netscape fouled anything here.
>

I can't see anything from Chris' message in Mohits message so
again this appears to be a thing Mozilla/Netscape fouls. I would
post Mohits message here again, but it's a bit long and I think
you should be able to chek the post again.

Dave Vandervies

unread,
Aug 24, 2001, 2:09:20 PM8/24/01
to
In article <3B85E83E...@eton.powernet.co.uk>,
Richard Heathfield <bin...@eton.powernet.co.uk> wrote:

>I don't think so. I think it means his (Chuck's) newsfeed is not getting
>100% of the posts. I've noticed that, if A posts, and B and C both reply
>directly to A, but my news server doesn't have A's article, then C's
>article is shown as a "child" of B's article in my newsreader, in order
>to avoid wrongly suggesting there are two threads here. I don't think
>that's a bug. I think it's one way to solve a problem. The other way is
>*not* to make C a child of B, in which case they would show up as two
>different threads and some people would complain that *that* was a bug.

The other other way is to put a nonexistent article (whose existence,
despite being contrary to the claims of the newsswerver, can be deduced
from the References header) at the root of the thread. This is what
trn does; an article is displayed along with a `map' of the thread that
looks something like this:

(1)+-(1)
\-(1)+-(1)--(1)
\-(1)+-(1)--(1)+-(1)
| \-(1)
\-(1)--(1)

(The '1's mean that all of these articles have the same subject line,
possibly with a `Re: ' prepended to later ones that doesn't exist in
the original.) Should an article not be avaliable, `( )' will be used
instead of `(1)':

( )+-(1)
\-( )+-(1)--(1)
\-(1)+-(1)--(1)+-(1)
| \-(1)
\-(1)--(1)

This means that neither the original post nor one of the replies to it
exist (or, at least, the newsswerver isn't aware of their existence),
but there are replies that have references that imply the existence of
those two posts.


ObC: This can be implemented in strictly conforming ANSI/ISO C, once
the program has the articles (getting them may require off-topic
extensions), except that the implementation with which I am familiar
uses a pager that does unbuffered input from the terminal.


dave

--
Dave Vandervies dj3v...@student.math.uwaterloo.ca

I don't think I was ever flamed. (Maybe I didn't try hard enough)
--Joe Wright in comp.lang.c

0 new messages