Trouble with scanf("%c", &answer);

P

Peter Mount

Hello

I'm having trouble with " scanf("%c", &answer);" on line 20 below. When I
run the program in cygwin on Windows 98SE it skips that line completely and
ends the program. Does scanf have problems with "%c" or is it the operating
system I'm using?

1 #include <stdio.h>
2
3 int main()
4 {
5 float width, length, area;
6 char answer;
7
8 do{
9 printf("\nEnter width of the rectangle ");
10 scanf("%f", &width);
11 printf("\nEnter length of the rectangle ");
12 scanf("%f", &length);
13
14 area = length * width;
15
16 printf("\nArea of the rectangle is %.2f", area);
17
18 printf("\nContinue? - Enter Y for yes, N for no ");
19
20 scanf("%c", &answer);
21
22 }while(answer == 'Y');
23
24 return 0;
25 }
26

Thanks

Peter Mount
(e-mail address removed)
 
A

Allan Bruce

Peter Mount said:
Hello

I'm having trouble with " scanf("%c", &answer);" on line 20 below. When I
run the program in cygwin on Windows 98SE it skips that line completely and
ends the program. Does scanf have problems with "%c" or is it the operating
system I'm using?

1 #include <stdio.h>
2
3 int main()
4 {
5 float width, length, area;
6 char answer;
7
8 do{
9 printf("\nEnter width of the rectangle ");
10 scanf("%f", &width);
11 printf("\nEnter length of the rectangle ");
12 scanf("%f", &length);
13
14 area = length * width;
15
16 printf("\nArea of the rectangle is %.2f", area);
17
18 printf("\nContinue? - Enter Y for yes, N for no ");
19
20 scanf("%c", &answer);
21
22 }while(answer == 'Y');
23
24 return 0;
25 }
26

Thanks

Peter Mount
(e-mail address removed)

Have a look at the FAQ - this is answered there nicely.
HINT: Your previous scanf() hasnt cleared the input buffer.
Allan
 
P

Peter Mount

Hello

I got it to work by changing line 20 to read:

scanf("%s", &answer);

Is this because I'm using Windows 98SE? I would have thought "scanf("%c",
&answer);" would have been correct as "answer" was declared as a char
variable.

Also, where is the FAQ? I'm using Outlook Express for my newsgroups so I
don't see the FAQ and I would like to read the FAQ if I could

Thanks

Peter Mount
(e-mail address removed)
 
C

CBFalconer

Peter said:
I'm having trouble with " scanf("%c", &answer);" on line 20 below.
When I run the program in cygwin on Windows 98SE it skips that
line completely and ends the program. Does scanf have problems
with "%c" or is it the operating system I'm using?

1 #include <stdio.h>
2
3 int main()
4 {
5 float width, length, area;
6 char answer;
7
8 do {
9 printf("\nEnter width of the rectangle ");
10 scanf("%f", &width);
11 printf("\nEnter length of the rectangle ");
12 scanf("%f", &length);
13
14 area = length * width;
15
16 printf("\nArea of the rectangle is %.2f", area);
17
18 printf("\nContinue? - Enter Y for yes, N for no ");
19
20 scanf("%c", &answer);

scanf(" %c", &answer);
21
22 } while(answer == 'Y');
23
24 return 0;
25 }
26

However you will have problems using scanf in interactive files.
You have also committed the fatal mistake of not checking the
scanf return value. The printf()s should be followed by
fflush(stdout);

You can handle most of these things with a couple of wrapper
functions:

#include <stdio.h>

void prompt(char *line)
{
printf(line);
fflush(stdout);
}

void getfloat(float *fv, char *promptln)
{
do {
prompt(promptln);
} while (1 != scanf("%f", fv))'
}

int getonechar(char *promptln)
{
int ch;

if (1 != scanf(" %c", ch)) return 0;
return (unsigned char) ch;
}

/* after which your routine reduces to: */

int main()
{
float width, length, area;

do {
getfloat(&width, "\nEnter width of the rectangle ");
getfloat(&length, "\nEnter length of the rectangle ");
area = length * width;
printf("\nArea of the rectangle is %.2f", area);
} while('Y' == toupper(getonechar(
"\nContinue? - Enter Y for yes, N for no ")));
return 0;
}

Notice how subroutines simplify and clarify. However that still
has all sorts of nasty problems for interactive use, because of
the use of scanf. Try responding to the first prompt with "2 3 Y"
(without the quotes) for example.
 
S

Shuvodeep

Hi Peter,
Just put in fflush(stdin) before line 20.This ensures that the
memory used for answer is initialized before using it again.I think
that will work.

Thanks.
Shuvodeep.
 
A

Arthur J. O'Dwyer

Hi Peter,
Just put in fflush(stdin) before line 20.This ensures that the
memory used for answer is initialized before using it again.I think
that will work.

Of course it won't; 'fflush' has nothing to do with input.
And "Shuvodeep" shouldn't be top-posting.

-Arthur
 
T

Tom St Denis

Shuvodeep said:
Hi Peter,
Just put in fflush(stdin) before line 20.This ensures that the
memory used for answer is initialized before using it again.I think
that will work.

If I'm not mistaken you cannot fflush an input stream. It's implementation
defined.

A better solution is to use proper input such as a fgets/sscanf combo. That
has well defined behaviour and will sync to newlines [or filled
buffers... ;-)].

Tom
 
C

CBFalconer

Peter said:
Thanks for that

Please do not top post. Here are slightly better behaved versions
of the subroutines I posted. I actually tried these ones. They
still have nasty interactive behaviour. They require #include
<ctype.h>.

int flushln(FILE *f)
{
int ch;

while ((EOF != (ch = getc(f)) && ('\n' != ch))) continue;
return ch;
}

void getfloat(float *fv, const char *promptln)
{
do {
prompt(promptln);
} while ((1 != scanf("%f", fv)) && (EOF != flushln(stdin)));
}

int getonechar(const char *promptln)
{
char ch;

prompt(promptln);
if (1 != scanf(" %c", &ch)) return 0;
return (unsigned char) ch;
}
 
C

CBFalconer

Shuvodeep said:
Just put in fflush(stdin) before line 20.This ensures that the
memory used for answer is initialized before using it again. I
think that will work.

No, don't do that. fflush is only defined for output files. And
please do not top-post, it is considered rude in this newsgroup.
 
J

Jack Klein

If I'm not mistaken you cannot fflush an input stream. It's implementation
defined.

No, it is undefined. The term "undefined behavior" has a specific
definition in the C standard. The term "implementation-defined" has a
different and incompatible definition in the C standard.

Anything which the standard claims produces "undefined behavior" does
not and cannot be "implementation-defined".
A better solution is to use proper input such as a fgets/sscanf combo. That
has well defined behaviour and will sync to newlines [or filled
buffers... ;-)].

Now that is a good suggestion.
 
S

SDZ

Peter Mount said:
Hello

I'm having trouble with " scanf("%c", &answer);" on line 20 below. When I
run the program in cygwin on Windows 98SE it skips that line completely and
ends the program. Does scanf have problems with "%c" or is it the operating
system I'm using?

1 #include <stdio.h>
2
3 int main()
4 {
5 float width, length, area;
6 char answer;
7
8 do{
9 printf("\nEnter width of the rectangle ");
10 scanf("%f", &width);
11 printf("\nEnter length of the rectangle ");
12 scanf("%f", &length);
13
14 area = length * width;
15
16 printf("\nArea of the rectangle is %.2f", area);
17
18 printf("\nContinue? - Enter Y for yes, N for no ");
19
20 scanf("%c", &answer);
21
22 }while(answer == 'Y');
23
24 return 0;
25 }
26

Thanks

Peter Mount
(e-mail address removed)


The problem is that the scanf on line 12 does not consume the last
character pressed after entering the length. That left over character
is consumed by the scanf on line 20. A simple patch would be this:

/* Declare a variable cahr dummy */
/* Dummy will consume the character and answer will have the character
typed - either Y or N */

scanf("%c %c", &dummy, &answer);

Hope this helps.

-SDZ
 
A

Allan Bruce

Peter Mount said:
Hello

I got it to work by changing line 20 to read:

scanf("%s", &answer);

Is this because I'm using Windows 98SE? I would have thought "scanf("%c",
&answer);" would have been correct as "answer" was declared as a char
variable.

Also, where is the FAQ? I'm using Outlook Express for my newsgroups so I
don't see the FAQ and I would like to read the FAQ if I could

Thanks

http://www.eskimo.com/~scs/C-faq/top.html
 
R

RoSsIaCrIiLoIA

Please do not top post. Here are slightly better behaved versions
of the subroutines I posted. I actually tried these ones. They
still have nasty interactive behaviour. They require #include
<ctype.h>.

int flushln(FILE *f)
int flushln(FILE* f, int prec)
{
int ch; int ch=prec;

while ((EOF != (ch = getc(f)) && ('\n' != ch))) continue;
if( prec!='\n' && prec!=EOF )
while( EOF!=(ch = getc(f)) && '\n'!=ch )
return ch;
}

Is this the real flush?
void getfloat(float *fv, const char *promptln)
{ int c;
do {
prompt(promptln);
} while ((1 != scanf("%f", fv)) && (EOF != flushln(stdin)));
while( (c = scanf("%f", fv))!=1 &&
c!=EOF && EOF!=flushln(stdin,'a') );

for you if c==EOF there will be the ask for input (flushln)
What do you say?
 
Z

Zoran Cutura

Peter Mount said:
Hello

I got it to work by changing line 20 to read:

scanf("%s", &answer);

which is not the correct sollution but just appears to be doing what
you're expecting right now.
Is this because I'm using Windows 98SE?

No. The problem will araise on all plattforms with a correct C
implementation.
I would have thought "scanf("%c",
&answer);" would have been correct as "answer" was declared as a char
variable.

Yes and no.

Look, the problem in not related to how scanf interprets the input, but
what is in the inputstream when your program reaches this call.
Also, where is the FAQ? I'm using Outlook Express for my newsgroups so I
don't see the FAQ and I would like to read the FAQ if I could

http://www.eskimo.com/~scs/C-faq/top.html
 

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,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top