HelloWorld
HelloWorld

Reputation: 21

Weird result of using scanf "%f" to read a float number and then assign to double

I just met a problem in C. Following is the code:

#include <stdio.h>

int main() {

    double num = 0;

    printf("Please enter a number: ");
    scanf("%f", &num);
    printf("The entered number is %f", num);

    return 0;
}

For some reason, no matter what number is entered from keyboard, the value of num keeps the same as 0. Of course, if I change the data type of num to float, then everything will be fine. But I just want to know why the above code does not work. My understanding is C automatically converts float to double, so the above code should work fine. I wonder if anybody can kindly provide further explanation.

Thanks.

Upvotes: 2

Views: 208

Answers (2)

Andreas Wenzel
Andreas Wenzel

Reputation: 25385

The correct scanf conversion format specifier for double is %lf, not %f. By using the wrong specifier, your program is invoking undefined behavior, which means that anything can happen (i.e. your program may crash or print wrong output).

My understanding is C automatically converts float to double

This statement is correct for printf, but not for scanf. When calling printf with a float variadic argument, the float is promoted to double. This is called a default argument promotion. However, a float * is never promoted to a double *. This applies both to printf and scanf, but is more relevant to scanf, because scanf makes more use of pointers.

The underlying reason for this behavior is that with printf, variables are passed by value, so that a float can easily be promoted to a double and printf therefore does not have to distinguish between a float and a double. However, with scanf, variables are usually passed by pointer, because scanf is not interested in the value of a variable, but rather its address, as it needs to know where to write the value of the variable. In order to write the value, scanf must also know the type and size of the variable. Therefore, scanf must distinguish between a float and a double.

Upvotes: 8

Florin C.
Florin C.

Reputation: 613

Use the %lf format specifier to read a double.

Upvotes: 2

Related Questions