Scanf/Printf double variable C

311,360

Solution 1

For variable argument functions like printf and scanf, the arguments are promoted, for example, any smaller integer types are promoted to int, float is promoted to double.

scanf takes parameters of pointers, so the promotion rule takes no effect. It must use %f for float* and %lf for double*.

printf will never see a float argument, float is always promoted to double. The format specifier is %f. But C99 also says %lf is the same as %f in printf:

C99 §7.19.6.1 The fprintf function

l (ell) Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long int or unsigned long int argument; that a following n conversion specifier applies to a pointer to a long int argument; that a following c conversion specifier applies to a wint_t argument; that a following s conversion specifier applies to a pointer to a wchar_t argument; or has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.

Solution 2

When a float is passed to printf, it is automatically converted to a double. This is part of the default argument promotions, which apply to functions that have a variable parameter list (containing ...), largely for historical reasons. Therefore, the “natural” specifier for a float, %f, must work with a double argument. So the %f and %lf specifiers for printf are the same; they both take a double value.

When scanf is called, pointers are passed, not direct values. A pointer to float is not converted to a pointer to double (this could not work since the pointed-to object cannot change when you change the pointer type). So, for scanf, the argument for %f must be a pointer to float, and the argument for %lf must be a pointer to double.

Solution 3

As far as I read manual pages, scanf says that 'l' length modifier indicates (in case of floating points) that the argument is of type double rather than of type float, so you can have 'lf, le, lg'.

As for printing, officially, the manual says that 'l' applies only to integer types. So it might be not supported on some systems or by some standards. For instance, I get the following error message when compiling with gcc -Wall -Wextra -pedantic

a.c:6:1: warning: ISO C90 does not support the ‘%lf’ gnu_printf format [-Wformat=]

So you may want to doublecheck if your standard supports the syntax.

To conclude, I would say that you read with '%lf' and you print with '%f'.

Share:
311,360

Related videos on Youtube

Dragos Rizescu
Author by

Dragos Rizescu

Working with bits for fun & profit

Updated on November 19, 2020

Comments

  • Dragos Rizescu
    Dragos Rizescu over 3 years

    Let's say I have this following bit of code in C:

    double var;
    scanf("%lf", &var);
    printf("%lf", var);
    printf("%f", var);
    

    It reads from stdin variable 'var' and then prints twice in stdout 'var'. I understand that's how you read a double variable from stdin, but my questions are:

    1. Why can you print a double with %lf?
    2. Why can you print a double with %f?
    3. Which one is better and correct to use?
  • chux - Reinstate Monica
    chux - Reinstate Monica over 10 years
    If one uses the C99 and C11 spec as "officially", they say "l ... has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.".
  • Eric Postpischil
    Eric Postpischil over 10 years
    What is “the manual“? This is not a useful reference without a title and version. Additionally, the current year is 2013, so using software specifications from 1990 when more modern versions are available should be discouraged.