user6913230
user6913230

Reputation:

Basic scanf statement error

I am writing a basic program to tell the user whether or not they have received enough sleep. However no matter how many hours are entered it always displays the first message of "Sleep Deprived" even if they've slept 10 hours.

double hoursOfSleep;

printf("Please enter the amount of hours of sleep you received last night:\n");
scanf("%f", &hoursOfSleep);

if (hoursOfSleep <= 4){
    printf("Sleep deprived!\n");}
else if (hoursOfSleep <= 6){
    printf("You need more sleep.\n");}
else if (hoursOfSleep <= 8){
    printf("Not quite enough.\n");}
else
    printf("Well Done!\n");

Upvotes: 2

Views: 202

Answers (4)

Hasib
Hasib

Reputation: 19

You are using %f for taking input double value. %f is used for floats. For double, it is %lf.

scanf("%lf", &hoursOfSleep);

%d for int

%c for char

%s for string

%lld for long long int

Upvotes: 0

ad absurdum
ad absurdum

Reputation: 21356

It is because you have a format specifier for a floating point number in your scanf(). You should use %lf for a double:

scanf("%lf", &hoursOfSleep);

When you don't match the format specifier to the type of the variable in a printf() or scanf(), you will have an unexpected result. When I entered 6 while running your code on my system, the float hoursOfSleep held the value 0.000000.

This sort of problem can be caught at compile time by enabling some compiler warnings. For example, I always at least have:

gcc nosleep.c -Wall -o nosleep

The -Wall switch enables several warnings, and the second I compiled your code I could see what was wrong. In fact, I would urge you to try compiling your broken code with the -Wall switch to see what happens. This kind of thing happens all the time; it is easy to forget one of the variables on the right side of a printf(), and with warnings enabled you find it right away.

Upvotes: 2

4386427
4386427

Reputation: 44368

As others have already mentioned, you must use %lf for double when using scanf. This is a bit confusing as doubles are printed with %f but that's how it is.

What I want to add is: Always check the value returned by scanf

Your current code has undefined behavior if the user inputs something not being a double. So at least do:

if (scanf("%lf", &hoursOfSleep) != 1)
{
    // Add error handling here
    hoursOfSleep = 8;  // At least initialize the variable...
}

A better approach could be:

char input[100];
while(1)
{
    printf("Please enter the amount of hours of sleep you received last night:\n");
    if (fgets(input, 100, stdin) == NULL)
    {
        printf("stdin error\n");
        return -1;
    }

    if (sscanf(input, "%lf", &hoursOfSleep) == 1)
    {
        // Got a double - break the loop
        break;
    }
}

Upvotes: 1

Jam
Jam

Reputation: 642

Try something like this:

scanf("%lf",&hoursOfSleep);

Because you specified %f, you told scanf() to expect a float *, but you passed it a double *. Using "%lf" specifies that you are requesting a double value (passing a double *).

Upvotes: 4

Related Questions