0

I've had this problem with a couple of programs now, and I can not figure out why this keeps happening. This is my code:

#include <stdio.h>
#include <math.h>

int main(void){

    double x = 0;

    while(x <= 0){
       printf("Enter a digit greater than 0.\n");
       scanf("%lf", &x);
    }

    printf("%lf", &x);
}

and the output is:

Enter a digit greater than 0.
4
0.000000

please help

sg7
  • 6,108
  • 2
  • 32
  • 40
CWhite
  • 9
  • 1
  • 1
    Sure would help to check the return of `scanf` so you know if your input succeeded... – David C. Rankin Mar 09 '18 at 02:00
  • Note that "enter a digit" implies a single digit; you should refer to a number if you mean non-integral value or values from 10.00 upwards are allowed. – Jonathan Leffler Mar 09 '18 at 02:10
  • Possible duplicate of [Why does scanf() need "%lf" for doubles, when printf() is okay with just "%f"?](https://stackoverflow.com/questions/210590/why-does-scanf-need-lf-for-doubles-when-printf-is-okay-with-just-f) – phuclv Sep 09 '18 at 04:33

3 Answers3

4

Use the following code

#include <stdio.h>
#include <math.h>

int main(void){

    double x = 0;

    while(x <= 0){
        printf("Enter a digit greater than 0.\n");
       scanf("%lf", &x);
    }

    printf("%lf", x);   
}

You are using

printf("%lf", &x);

But the correct syntax to print value of x is:

printf("%lf", x);

Check the working code https://ideone.com/lpdlmX

sg7
  • 6,108
  • 2
  • 32
  • 40
Md Johirul Islam
  • 5,042
  • 4
  • 23
  • 56
4

First off,

printf ("%lf", &x);

will try to print the address of x rather than its value, and this is clearly into undefined behaviour territory(a). A half-decent compiler should warn you about this such as, with gcc:

program.c: In function 'main':
program.c:13: warning: format '%lf' expects argument of type
    'double', but argument 2 has type 'double *' [-Wformat=]
 printf ("%lf\n", &x);
         ^

Secondly, the normal printf specifier for double is %f rather than %lf. You can use the latter since the standard states it has no effect on certain data types but it's a bit of a waste doing so.

So what you need is actually:

printf ("%f", x);

The general rule is that you pass addresses to scanf because it needs to populate the objects at those addresses. For printf, you just pass the object itself (yes, even if the data is a pointer that you want printed as a pointer rather than pointing the object being pointed to).


And, finally, to make your code more robust, you would be wise to detect a problem with scanf since, it there's a problem with the input that leaves x set to zero, the program will continuously try to read that input, resulting in an infinite loop.

So a good starting point, taking all those comments into consideration, would be:

#include <stdio.h>
#include <math.h>

int main (void) {
    double x = 0;

    while (x <= 0) {
        printf ("Enter a digit greater than 0.\n");
        if (scanf ("%lf", &x) != 1) {
            printf ("Invalid input\n");
            return 1;
        }
    }

    printf ("%f\n", x);
    return 0;
}

(a) Specifically, from ISO C11 7.21.6.1 /9:

If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
3

Always always check the return of scanf, that being said, you printf ("%f", x); -- there is no &x and no need for %lf, printf %f format specifiers prints doubles. (however it is required when using scanf -- man scanf and man printf are your friends)

Putting it altogether, you could safely take input as follows:

#include <stdio.h>

int main (void) {

    double x = 0;

    while(x <= 0){
        printf ("Enter a digit greater than 0.\n");
        if (scanf ("%lf", &x) != 1) {
            fprintf (stderr, "error: invalid input.\n");
            return 1;
        }
    }

    printf ("%f", x);

}

note: you must exit the loop on conversion failure (or empty stdin before attempting to take input again -- or your input will fail) Reason: on a failed conversion - no additional characters are read leaving the characters causing the failure just waiting to bite you again on the next go-round...

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85