Why does scanf() need "%lf" for doubles, when printf() is okay with just "%f"?
Why is it that scanf()
needs the l
in "%lf
" when reading a double
, when printf()
can use "%f
" regardless of whether its argument is a double
or a float
?
Example code:
double d;
scanf("%lf", &d);
printf("%f", d);
Because C will promote floats to doubles for functions that take variable arguments. Pointers aren't promoted to anything, so you should be using %lf
, %lg
or %le
(or %la
in C99) to read in doubles.
Since С99 the matching between format specifiers and floating-point argument types in C is consistent between printf
and scanf
. It is
-
%f
forfloat
-
%lf
fordouble
-
%Lf
forlong double
It just so happens that when arguments of type float
are passed as variadic parameters, such arguments are implicitly converted to type double
. This is the reason why in printf
format specifiers %f
and %lf
are equivalent and interchangeable. In printf
you can "cross-use" %lf
with float
or %f
with double
.
But there's no reason to actually do it in practice. Don't use %f
to printf
arguments of type double
. It is a widespread habit born back in C89/90 times, but it is a bad habit. Use %lf
in printf
for double
and keep %f
reserved for float
arguments.
scanf
needs to know the size of the data being pointed at by &d
to fill it properly, whereas variadic functions promote floats to doubles (not entirely sure why), so printf
is always getting a double
.
Because otherwise scanf will think you are passing a pointer to a float which is a smaller size than a double, and it will return an incorrect value.