As answered by @Chris McGrath, you must use the %lf format specifier for doubles. However, this doesn't explain why the %f format works just fine for printf.
%lf stands for long float, i.e. double. When values of type float are passed to variadic functions (those accepting a variable number of arguments, such as printf and scanf), they are implicitly promoted to double:
float val;
printf("%f", val); /* printf receives val cast to double, the same
as printf("%f", (double) val) */
printf("%lf", val); /* printf also receives val cast to double, the
same as printf("%lf", (double) val) */
Since both printf("%lf", ...) and printf("%f", ...) end up receiving a double, the two are completely equivalent.
On the other hand, all arguments to scanf are pointers. scanf("%f", ...) expects to receive a float *, and scanf("%lf", ...) a double *:
float floatval;
double dblval;
scanf("%f", &floatval); /* stores a float value to address received */
scanf("%lf", &dblval); /* stores a double value to address received */
The two pointers point to different types, so one cannot be promoted to the other. If they received the same treatment by scanf, it would end up storing the same value into addresses allocated for types of different size, which cannot work.
This is why scanf strictly requires the use of the %lf specifier when used with double values.