0

I'm a beginner at learning C and am using CodeStepByStep to practice, but I've recently been stuck at the receipt2 exercise:

The following console program always computes the same output. Modify it to be an interactive program that prompts the user to enter the meal cost as shown and computes the rest of the values based on that meal cost. Here are two example logs of execution:

What was the meal cost? $50
Subtotal: $50.00
Tax: $4.00
Tip: $7.50
Total: $61.50
What was the meal cost? $125
Subtotal: $125.0
Tax: $10.00
Tip: $18.75
Total: $153.75

This is the code I came up with:

int main() {
    
    double subtotal;
    double tax = subtotal * .08;
    double tip = subtotal * .15;
   double total = subtotal + tax + tip;
    
    printf("What was the meal cost? $");
    scanf("%1f\n", &subtotal);
    
    printf("Subtotal: $%.2f\n", subtotal);
    printf("Tax: $%.2f\n", tax);
    printf("Tip: $%.2f\n", tip);
    printf("Total: $%.2f\n", total);
    return 0;
}

And this is what I get:

What was the meal cost? $50
Subtotal: $1487596185306552356576543796496142744039674099895955705687117069098083127278735...
Tax: $119007672208353363661503531346055809843579575493495085918530749993454701233205893051...
Tip: $223139385390662542606067286932452039577591885184656158736966400576173810359277903991...
Total: $1829742960203432862406782001386817676654305864334200732372522204186617249017377688...

I'm not sure what caused this so I'd greatly appreciate an explanation as well as a possible solution.

Thank you!

Bob Bob
  • 3
  • 2
  • You need to do the calculations _after_ you've entered the `subtotal`. Also, your `scanf` format is wrong. It should be `scanf("%lf\n", &subtotal);`. You also need to `#include ` – Ted Lyngmo Aug 02 '22 at 14:25
  • 1
    `"%1f\n"` will read at most one character. If you type `50`, it will read the `5`, assigning `5.0` to `subtotal` and immediately return. If you type `5`, it will assign 5.0 and block until some non-whitespace character is entered. As a beginner, avoid `scanf` like the plague. The time you spend learning its foibles would be better spend elsewhere. – William Pursell Aug 02 '22 at 14:27
  • But....`subtotal` is of type `double`, so using a `%f` conversion specifier leads to undefined behavior. – William Pursell Aug 02 '22 at 14:29
  • 1
    One problem is the trailing newline in the `scanf()` format string. Normally, that would give major problems with the input 'not terminating' — see [What is the effect of trailing white space in a `scanf()` format string?](https://stackoverflow.com/q/15740024/15168) However, you have a compensating bug: you specify `%1f` which means `scanf()` looks for a single digit, and then for a non-space character. Because you typed 50, the `0` serves as a non-space character and the input terminates. Since you're trying to read a `double`, you should be using `%lf` (lower-case letter ell). – Jonathan Leffler Aug 02 '22 at 14:53
  • The improperly initialized values are huge, so printing them with 2 decimal places prints a lot of digits before the decimal point and 2 digits afterwards. – Jonathan Leffler Aug 02 '22 at 14:54

1 Answers1

2

The reason for the strange numbers you get is that you read from subtotal while it's uninitialized and that you're using the wrong scanf format to read a double, 1f instead of lf. The former reads 1 character into a float. Both these leads to undefined behavior and the program could therefore do just about anything - like crash or print strange numbers. Also note that you shouldn't have the trailing \n in your scanf format string.

You also need to do the calculations after you've entered the subtotal and you need to #include <stdio.h>. You should also check that scanf actually succeeds.

Example:

#include <stdio.h> // added missing header

int main(void) {
    double subtotal;

    printf("What was the meal cost? $");

    // corrected scanf format:
    if(scanf("%lf", &subtotal) != 1) return 1; // checking that it succeeded

    // doing the calculations after you've read the subtotal:
    double tax = subtotal * .08;
    double tip = subtotal * .15;
    double total = subtotal + tax + tip;
    
    printf("Subtotal: $%.2f\n", subtotal);
    printf("Tax: $%.2f\n", tax);
    printf("Tip: $%.2f\n", tip);
    printf("Total: $%.2f\n", total);
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108