3

So what is happening is I ask the user for input, then store that into a variable using scanf.

But when I try to retrieve the value, it just a 0.000000. I'm sure I'm just making a stupid noob mistake, but any help you can provide is appreciated.

printf("Enter the radius of your circle/sphere: ");
scanf("%f", &radius);

printf("\n%f", radius);

Ex:

Enter the radius of your circle/sphere: 10

0.0000000

Thanks for your time!

UnlovedPanda
  • 53
  • 1
  • 5

2 Answers2

5

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.

user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • `long float` is not a synonym for `double`, it's a syntax error. The floating-point types are `float`, `double`, and `long double`. – Keith Thompson Mar 05 '14 at 22:15
  • @KeithThompson Corrected, thanks. BTW you made the same error in your comment. – user4815162342 Mar 05 '14 at 22:18
  • 1
    Not anymore I didn't! – Keith Thompson Mar 05 '14 at 22:19
  • @user4815162342: I have previously asked a similar question and got sort of an opposite answer: http://stackoverflow.com/q/21443160/1382251... Well, to be more accurate, I asked how come `printf("%f",x)` works for both `float x` and `double x`. Can you please refer to that (if not too hard)? Thanks. – barak manos Mar 05 '14 at 22:29
  • @barakmanos The answer to that question is essentially the same as the first part of my answer, where I explain why `%f` and `%lf` are the same for `printf`. This answer goes one step further to explain how come the two are **not** the same for `scanf`, which doesn't directly receive variadic floating-point values, but pointers to ones. Pointers don't (and can't) fall under the default promotion rules, so `%lf` and `%f` must do different things in order to store values of different types. [Another answer](http://stackoverflow.com/a/210591/1600898) states the same, but doesn't explain why. – user4815162342 Mar 05 '14 at 22:35
  • @user4815162342: Oh!!!!!! `scanf` takes pointers, of course!!! Sorry, I should have realized that (or read your answer a little more carefully)... Thanks, gave you a tenner :) – barak manos Mar 05 '14 at 22:37
  • Additional note: C89 doesn't have `printf("%lf", ...)`, although many compilers implemented it as an extension. It wasn't formally added until C99. C89 specifies that `%f` is the specifier for both `float` and `double`. – M.M Mar 06 '14 at 10:09
  • Thanks for the explanation. I really appreciate understanding the logic behind the fix, not just the fix itself. All of you have been very helpful. Thanks again! – UnlovedPanda Mar 06 '14 at 19:27
0

As AntonH said, if radius is declared as a double, you must use the %lf format specifier:

scanf("%lf", &radius);
Chris McGrath
  • 1,936
  • 16
  • 17