scanf for char input getting skipped

F

FerrisUML

Hello everyone! I new to C and am having the following problem. In
the below program, the last scanf is being ignored and the program
exits. Can anyone see anything that im doing wrong? Thanks in
advance.

#include <stdio.h>

/*
HOMEWORK: Assignment 1
Name: Dennis McQuilken
Class: C Programming
Date: 9.19.2008
Description: This is a C program that will calculate an employees
gross pay based on hours work and hourly rate.
*/


int main()
{

int clock_number = 0;
float hours_worked = 0;
float hourly_rate = 0;
float total = 0;
char quitVal;

goto start;

start:

printf("Please enter the employee's clock number:\n");
scanf("%i", &clock_number);
printf("Please enter the employee's hourly rate:\n");
scanf("%f", &hourly_rate);
printf("Please enter the hours worked:\n");
scanf("%f", &hours_worked);
total = hourly_rate * hours_worked;
printf("Employee Clock Number\tHourly Rate\tHours Worked\tGross\n");
printf("%i\t\t\t%0.2f\t\t%0.2f\t\t%0.2f\n", clock_number,
hours_worked, hourly_rate, total);
printf("Do you want to quit:");
scanf("%c", &quitVal);
goto done;

done:

return 0;
}
 
F

FerrisUML

FerrisUML said:


No, it isn't being ignored.


Yes. I have removed from your program everything that is not relevant to
this specific problem.





This shorter program will give you the same problem - it appears to ignore
the second scanf. But in fact it is not doing so.

Let's say your hours_worked value is 4.2 - so what do you type? It's no
good just typing 4.2 because the cursor will sit there blinking at you, in
case you're about to add a 5 to make it 4.25, yes?

So you press ENTER to signify to your command processor that you've
finished this line of data. The characters '4', '.', '2', '\n' are now
made available to your C program on its standard input stream. The scanf
munches the '4', '.', and '2' to make 4.2, but '\n' isn't part of a
floating point value, so scanf leaves it in the stream.

Your next scanf reads a single character from stdin. Oh look, there's a
'\n' waiting - that'll do nicely, and there's no need to gather more input
from the user.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

I had a feeling whomever responded would say that. Whats the best way
to clear the input stream buffer before peforming a scanf? I've
researched and found the following, but im not sure if its the best
approach seeing as I have to swap scanf for getchar.


printf("Would you like to calculate for another employee? (y/n)\n");
while(getchar() != '\n') continue;
if(getchar() == 'y')
{
goto start;
}
else
{
goto done;
}
 
A

Andrew Poelstra

Hello everyone! I new to C and am having the following problem. In
the below program, the last scanf is being ignored and the program
exits. Can anyone see anything that im doing wrong? Thanks in
advance.

#include <stdio.h>

/*
HOMEWORK: Assignment 1
Name: Dennis McQuilken
Class: C Programming
Date: 9.19.2008
Description: This is a C program that will calculate an employees
gross pay based on hours work and hourly rate.
*/

Thanks! This is a first that I've seen, anyway - it's clear you
know how to ask for help with homework here, the intelligent way.
int main()

int main(void) is better style, FWIW.
{

int clock_number = 0;
float hours_worked = 0;
float hourly_rate = 0;
float total = 0;
char quitVal;

goto start;

start:

What is the point of this? You do it again below, but goto is
(almost) never a good idea, and certainly isn't needed here.
printf("Please enter the employee's clock number:\n");
scanf("%i", &clock_number);
printf("Please enter the employee's hourly rate:\n");
scanf("%f", &hourly_rate);
printf("Please enter the hours worked:\n");
scanf("%f", &hours_worked);
total = hourly_rate * hours_worked;
printf("Employee Clock Number\tHourly Rate\tHours Worked\tGross\n");
printf("%i\t\t\t%0.2f\t\t%0.2f\t\t%0.2f\n", clock_number,
hours_worked, hourly_rate, total);
printf("Do you want to quit:");
scanf("%c", &quitVal);
goto done;

done:

return 0;
}

Your problem is the way that scanf() works. The first time it
encounters %i, it skips whitespace until it finds something
integer-looking, and then reads up until it finds something
not integer-looking.

In each case, the first non-integer-looking something will be
the newline character you enter when you hit enter after typing
a number. It puts this newline back so that the next input
function can get it if it needs.

This doesn't matter for next two %f specifiers, because like
%i, they skip whitespace until they find something number-
looking.

BUT, this is not true for %c - it takes that newline there
and happily accepts it as input. Since that's enough to satisfy
it, it doesn't bother requesting the user for something more.
This causes it to "ignore" the last scanf().

I don't remember how to work around this using scanf(), but
I personally would use fgets() to read input a line-at-a-time
and then parse it myself. That way, if my boss comes in and
says "users are trying to type in the word 'one' and expecting
your program to still work" it's a little easier to adapt the
parsing logic.
 
K

Keith Thompson

FerrisUML said:
Hello everyone! I new to C and am having the following problem. In
the below program, the last scanf is being ignored and the program
exits. Can anyone see anything that im doing wrong? Thanks in
advance.
[...]

The comp.lang.c FAQ is an excellent resource, available at
<http://www.c-faq.com/>. You've just asked question 12.18b.
 
C

CBFalconer

Richard said:
FerrisUML said:


No, it isn't being ignored.


Yes. I have removed from your program everything that is not relevant to
this specific problem.


This shorter program will give you the same problem - it appears to ignore
the second scanf. But in fact it is not doing so.

Let's say your hours_worked value is 4.2 - so what do you type? It's no
good just typing 4.2 because the cursor will sit there blinking at you, in
case you're about to add a 5 to make it 4.25, yes?

So you press ENTER to signify to your command processor that you've
finished this line of data. The characters '4', '.', '2', '\n' are now
made available to your C program on its standard input stream. The scanf
munches the '4', '.', and '2' to make 4.2, but '\n' isn't part of a
floating point value, so scanf leaves it in the stream.

Your next scanf reads a single character from stdin. Oh look, there's a
'\n' waiting - that'll do nicely, and there's no need to gather more input
from the user.

That's all very well, but you neglect the fundamental requirement
for using scanf interactively. CHECK THE RETURNED VALUE. This
allows discovering failures in the scanf call.

All calls should be of the form

if (NUMBER == scanf(...)) { /* accepted */ }
else { /* rejected */ )

with suitable values for NUMBER, and possible retention of the
returned value.
 
R

Richard

CBFalconer said:
That's all very well, but you neglect the fundamental requirement
for using scanf interactively. CHECK THE RETURNED VALUE. This
allows discovering failures in the scanf call.

All calls should be of the form

if (NUMBER == scanf(...)) { /* accepted */ }
else { /* rejected */ )

with suitable values for NUMBER, and possible retention of the
returned value.

There's only one type of retention in that needless post and its not
return code retention.
 
R

Richard

Richard Heathfield said:
CBFalconer said:


For the sake of your students, I sincerely hope you're not a teacher.

One thing at a time, dude. Give the guy time to get over the shock of
discovering that scanf isn't as clever as he thought. There's plenty of
time later on to reveal that it's cleverer than he thought.

Please see threads on pointers for further "how to confuse students" by
denying reality and living in a dusty standard.
 
C

CBFalconer

Richard said:
CBFalconer said:

For the sake of your students, I sincerely hope you're not a teacher.

One thing at a time, dude. Give the guy time to get over the shock
of discovering that scanf isn't as clever as he thought. There's
plenty of time later on to reveal that it's cleverer than he thought.

I'm not, but that doesn't remove the fact that the first thing to
do is check that returned value. If the OP realized that scanf was
reporting an error he might have figured it all out on his own.
 
J

James Kuyper

FerrisUML said:
Hello everyone! I new to C and am having the following problem. In
the below program, the last scanf is being ignored and the program
exits. Can anyone see anything that im doing wrong? Thanks in
advance.

You posted an almost identical message to comp.lang.c.moderated. In
general, cross-posting should be avoided. However, if you must
cross-post, you should send a single message to both groups, rather than
a separate but identical message to each group. That way any discussion
of the issue that appears on either group can be seen by people who
monitor either group.

See my reply to your message on clcm, when it gets through the
moderation queue. The slow pace of the moderation queue is one key
reason why clcm is less popular than clc. The absence of a moderator is
the key reason so many obnoxious and off-topic messages clog up clc.

As far as I can tell, this is the only part of the program that was
missing from your clcm post:
#include <stdio.h>

/*
HOMEWORK: Assignment 1
Name: Dennis McQuilken
Class: C Programming
Date: 9.19.2008
Description: This is a C program that will calculate an employees
gross pay based on hours work and hourly rate.
*/

I should have told you that <stdio.h> was missing from you clcm message;
but I'm not as good as I should be at noticing that particular kind of
defect in other people's code.
 
J

jameskuyper

James Kuyper wrote:
....
You posted an almost identical message to comp.lang.c.moderated. In ....
moderation queue. The slow pace of the moderation queue is one key
reason why clcm is less popular than clc. ...

I hadn't intended to provide such dramatic evidence of "the slow
pace". I posted that message on 2008-09-17, before anyone else's
responses had yet shown up, on my newsserver, though you couldn't tell
that by looking at the message headers. 11 days to get through the
moderation queue?!
 

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,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top