weirdness of scanf

K

Kevin Zhou

#include <stdio.h>

main()
{
double a;
scanf("%f", &a);
printf("%f",a);
}
the output is always -1.998295 no matter what value i put in

but

#include <stdio.h>

main()
{
int a;
scanf("%d", &a);
printf("%d",a);
}

works wine
 
K

Kevin Zhou

Kevin said:
#include <stdio.h>

main()
{
double a;
scanf("%f", &a);
printf("%f",a);
}
the output is always -1.998295 no matter what value i put in

but

#include <stdio.h>

main()
{
int a;
scanf("%d", &a);
printf("%d",a);
}

works wine

problem solved
should have used scanf("%lf",&a)
in K&R lf looks like 1f and it doesn't explain why
 
L

Leor Zolman

problem solved
should have used scanf("%lf",&a)
in K&R lf looks like 1f and it doesn't explain why

So, do you understand why, now? There /must/ be two different format
conversions for float and double, because the types have different storage
requirements (at least on most systems), and scanf has to know exactly how
wide the object is it's modifying.

The reason this may come as a surprise to beginners is that the
printf-family doesn't distinguish those types. But that's because floats
get promoted to doubles automatically during the call, so the
printf-family functions still see doubles, even when the caller writes
arguments of type float in the argument list.
-leor
 
M

Martin Ambuhl

Kevin said:
#include <stdio.h>

main()
^
The return type of main is int; you should say so. When you get a C99
compiler, you will be *required* to say so.
{
double a;
scanf("%f", &a);
^^
The scanf specifier for double is "%lf".
printf("%f",a);
^^^
Without an end-of-line character terminating the last line of output,
the behavior of your program is not predictable across platforms.
}
the output is always -1.998295 no matter what value i put in

Try this version instead:

#include <stdio.h>

int main(void)
{
double a;
scanf("%lf", &a);
printf("%f\n", a);
return 0;
}
 
D

Dan Pop

In said:
The reason this may come as a surprise to beginners is that the
printf-family doesn't distinguish those types. But that's because floats
get promoted to doubles automatically during the call, so the
printf-family functions still see doubles, even when the caller writes
arguments of type float in the argument list.

Actually, most beginners who get it wrong expect printf to use %lf for
doubles. The mistake was popular enough for C99 to actually bless it and
%lf in printf is no longer undefined behaviour, as it was in C89.

Dan
 
L

Leor Zolman

Actually, most beginners who get it wrong expect printf to use %lf for
doubles. The mistake was popular enough for C99 to actually bless it and
%lf in printf is no longer undefined behaviour, as it was in C89.

Cool. I didn't know that. In beginning C classes I teach, though, despite
careful explanation of the conversions for scanf, there's typically someone
who'll use %f for doubles. I think it is a natural mistake, compounded by
the fact that trying to remember the conversions mnemonically by data type
is a non-starter [you mean %d isn't for doubles? :) ]
-leor
 

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,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top