-2

When I enter any characters except numbers in the "Enter your choice" it will infinitely loop. For example: Typing in a character. Result As, you can see it will just infinitely loop, unless I input a number between 1 to 10 as represented for each product choice. Or when typing in any number not between numbers 1 to 10, it will be recognized as an Invalid choice. P.S. Newbie Coder.

This is the code of the program.

#include <stdio.h>

int main(void)
{
    int choice, quantity, total = 0, price = 0;
    char end;

    do
    {
        printf("\nWelcome to our store!\n\n");
        printf("Welcome to our store!\n");
        printf("Please select a product from the following list:\n");
        printf("1. Oishi Prawn Crackers - 7 PHP\n");
        printf("2. Piattos - 16 PHP\n");
        printf("3. Coca-Cola - 40 PHP\n");
        printf("4. Sting Energy Drink - 25 PHP\n");
        printf("5. Gatorade - 43 PHP\n");
        printf("6. Nature Spring 500mL - 10 PHP\n");
        printf("7. KitKat - 30 PHP\n");
        printf("8. Snickers - 44 PHP\n");
        printf("9. Oishi Prawn Crackers - 7 PHP\n");
        printf("10. M&M's - 80 PHP\n");
        printf("Enter 0 to finish.\n");
        printf("\nProduct                 Quantity   Price\n");
        printf("----------------------------------------\n");

        do
        {
            printf("Enter your choice: ");
            scanf(" %d", &choice);

            if (choice == 0)
            {
                break;
            }

            printf("Enter the quantity: ");
            scanf(" %d", &quantity);

            switch (choice)
            {
            case 1:
                printf("Oishi Prawn Crackers        %d        %d\n", quantity, price = 7 * quantity);
                total += 7 * quantity;
                break;
            case 2:
                printf("Piattos                     %d        %d\n", quantity, price = 16 * quantity);
                total += 15 * quantity;
                break;
            case 3:
                printf("Coca-Cola                   %d        %d\n", quantity, price = 40 * quantity);
                total += 40 * quantity;
                break;
            case 4:
                printf("Sting Energy Drink          %d        %d\n", quantity, price = 25 * quantity);
                total += 25 * quantity;
                break;
            case 5:
                printf("Gatorade 500mL              %d        %d\n", quantity, price = 43 * quantity);
                total += 43 * quantity;
                break;
            case 6:
                printf("Nature Spring 500mL         %d        %d\n", quantity, price = 10 * quantity);
                total += 10 * quantity;
                break;
            case 7:
                printf("KitKat                      %d        %d\n", quantity, price = 30 * quantity);
                total += 30 * quantity;
                break;
            case 8:
                printf("Snickers                    %d        %d\n", quantity, price = 44 * quantity);
                total += 44 * quantity;
                break;
            case 9:
                printf("M&M's                       %d        %d\n", quantity, price = 40 * quantity);
                total += 40 * quantity;
                break;
            case 10:
                printf("Pringles                    %d        %d\n", quantity, price = 80 * quantity);
                total += 80 * quantity;
                break;
            default:
                printf("Invalid choice.\n");
                break;
            }
        } while (choice != 0);

        printf("----------------------------------------\n");
        printf("Total cost: %d PHP\n", total);
        printf("Thank you for shopping with us!\n");
        printf("\nWant to Buy Again?\n");
        printf("Y if Yes\n");
        printf("Type any key if No\n");
        scanf(" %c", &end);

        switch (end) {
        case 'Y':
            printf("\nOK!\n");
            break;
        default:
            printf("\nBYE!\n");
            break;
        }
    } while (end == 'Y');
    return 0;
}

So, I typed in numbers from 1 to 10 and it seems to recognize every product and it will ask for the quantity. And typing in any numbers it will do what it should and will output Invalid Choice. I tried changing the variables expecting it to be fixed but it won't work at all. It seems that I overlooked something but I don't know where.

  • 1
    Always check the `scanf` return value... and add error handling if you don't get the expected return value, i.e. `if (scanf(" %d", &choice) != 1) { // Add error handling}` – Support Ukraine Jan 10 '23 at 11:02
  • Welcome to SO. Your first step should be do detect the problem. You should *always* check return value of `scanf`. If the input does not match the format specifier, the character is not consumed. You must remove it from the input manually. – Gerhardh Jan 10 '23 at 11:03
  • 1
    This will sound surprising, but: My advice to you is to *not* spend any time trying to solve this problem just now. It's a real problem, to be sure, but the only reasonable way to solve it is to *not use `scanf` at all*. But if you're just starting out, it can be quite convenient to use `scanf` for your first few weeks, despite its long-term uselessness. When you're ready, you can learn [how to do input using other (and better) techniques than `scanf`](https://stackoverflow.com/questions/58403537). – Steve Summit Jan 10 '23 at 13:18

2 Answers2

1

Consider using a structure to store the name and cost of each product. That will avoid errors in repetitions.
scanint and scanchar will scan and discard pending characters in the input stream. Extra non-whitespace characters will cause a re-prompt.

#include <stdio.h>

typedef struct item item_t;
struct item {
    char const *name;
    int cost;
};

int scanint ( char const *prompt);
int scanchar ( char const *prompt);
void menu ( size_t items, item_t product[]);

int main(void)
{
    item_t products[] = {
          { "Oishi Prawn Crackers",  7}
        , { "Piattos",              16}
        , { "Coca-Cola",            40}
        , { "Sting Energy Drink",   25}
        , { "Gatorade",             43}
        , { "Nature Spring 500mL",  10}
        , { "KitKat",               30}
        , { "Snickers",             44}
        , { "Pringles",              7}
        , { "M&M's",                80}
    };

    int choice = 0;
    int quantity = 0;
    int total = 0;
    char end = 0;
    size_t items = sizeof products / sizeof *products;

    do {
        printf("\nWelcome to our store!\n\n");
        menu ( items, products);

        while ( 1) {
            choice = scanint ( "Enter your choice: ");

            if (choice == 0) {
                break;
            }
            --choice;

            if ( choice < items) {
                quantity = scanint ( "\tEnter the quantity: ");

                printf ( "%-22s%3d %7d\n"
                , products[choice].name
                , quantity
                , products[choice].cost * quantity);
                total += products[choice].cost * quantity;
            }
            else {
                printf("Invalid choice.\n");
            }
        }

        printf ( "----------------------------------------\n");
        printf ( "Total cost: %d PHP\n", total);
        printf ( "Thank you for shopping with us!\n");

        end = scanchar ( "\nWant to Buy Again?\nY if Yes\nType any key if No\n");

        switch (end) {
        case 'Y':
            printf("\nOK!\n");
            break;
        default:
            printf("\nBYE!\n");
            break;
        }
    } while (end == 'Y');
    return 0;
}

void menu ( size_t items, item_t product[]) {
    printf ( "Please select a product from the following list:\n");
    for ( int each = 0; each < items; ++each) {
        printf ( "%2d. %-22s%3d PHP\n"
        , each + 1, product[each].name, product[each].cost);
    }
}

int scanint ( char const *prompt) {
    char newline[2] = "";
    int extra = 0;
    int scanned = 0;
    int value = 0;

    do {
        printf ( "%s", prompt);
        fflush ( stdout);
        scanned = scanf ( "%d", &value);
        if ( scanned == EOF) {
            return 0;
        }
        extra = 0;
        scanf ( "%*[ \f\t\v]"); // scan and discard whitespace except newline
        scanf ( "%*[^\n]%n", &extra); // scan discard and count not a newline
        scanned += scanf ( "%1[\n]", newline);
    } while ( value < 0 || scanned != 2 || extra != 0);

    return value;
}

int scanchar ( char const *prompt) {
    char newline[2] = "";
    int extra = 0;
    int scanned = 0;
    char value = 0;

    do {
        printf ( "%s", prompt);
        fflush ( stdout);
        scanned = scanf ( " %c", &value);
        if ( scanned == EOF) {
            return 0;
        }
        extra = 0;
        scanf ( "%*[ \f\t\v]"); // scan and discard trailing whitespace except newline
        scanf ( "%*[^\n]%n", &extra); // scan discard and count not a newline
        scanned += scanf ( "%1[\n]", newline);
    } while ( scanned != 2 || extra != 0);

    return value;
}
user3121023
  • 8,181
  • 5
  • 18
  • 16
-2

Here you go:

#include <stdio.h>

int main(void)
{
    int choice = 0, quantity, total = 0, price = 0;
    char end;

    do
    {
        printf("\nWelcome to our store!\n\n");
        printf("Welcome to our store!\n");
        printf("Please select a product from the following list:\n");
        printf("1. Oishi Prawn Crackers - 7 PHP\n");
        printf("2. Piattos - 16 PHP\n");
        printf("3. Coca-Cola - 40 PHP\n");
        printf("4. Sting Energy Drink - 25 PHP\n");
        printf("5. Gatorade - 43 PHP\n");
        printf("6. Nature Spring 500mL - 10 PHP\n");
        printf("7. KitKat - 30 PHP\n");
        printf("8. Snickers - 44 PHP\n");
        printf("9. Oishi Prawn Crackers - 7 PHP\n");
        printf("10. M&M's - 80 PHP\n");
        printf("Enter 0 to finish.\n");
        printf("\nProduct                 Quantity   Price\n");
        printf("----------------------------------------\n");

        do
        {
            int choice = 0;
            
            printf("Enter your choice: ");
            scanf(" %d", &choice);
            while ( getchar() != '\n' );
            if (choice == 0 || choice > 10)
            {
                break;
            }

            printf("Enter the quantity: ");
            scanf(" %d", &quantity);

            switch (choice)
            {
            case 1:
                printf("Oishi Prawn Crackers        %d        %d\n", quantity, price = 7 * quantity);
                total += 7 * quantity;
                break;
            case 2:
                printf("Piattos                     %d        %d\n", quantity, price = 16 * quantity);
                total += 15 * quantity;
                break;
            case 3:
                printf("Coca-Cola                   %d        %d\n", quantity, price = 40 * quantity);
                total += 40 * quantity;
                break;
            case 4:
                printf("Sting Energy Drink          %d        %d\n", quantity, price = 25 * quantity);
                total += 25 * quantity;
                break;
            case 5:
                printf("Gatorade 500mL              %d        %d\n", quantity, price = 43 * quantity);
                total += 43 * quantity;
                break;
            case 6:
                printf("Nature Spring 500mL         %d        %d\n", quantity, price = 10 * quantity);
                total += 10 * quantity;
                break;
            case 7:
                printf("KitKat                      %d        %d\n", quantity, price = 30 * quantity);
                total += 30 * quantity;
                break;
            case 8:
                printf("Snickers                    %d        %d\n", quantity, price = 44 * quantity);
                total += 44 * quantity;
                break;
            case 9:
                printf("M&M's                       %d        %d\n", quantity, price = 40 * quantity);
                total += 40 * quantity;
                break;
            case 10:
                printf("Pringles                    %d        %d\n", quantity, price = 80 * quantity);
                total += 80 * quantity;
                break;
            default:
                printf("Invalid choice.\n");
                break;
            }
        } while (choice != 0);

        printf("----------------------------------------\n");
        printf("Total cost: %d PHP\n", total);
        printf("Thank you for shopping with us!\n");
        printf("\nWant to Buy Again?\n");
        printf("Y if Yes\n");
        printf("Type any key if No\n");
        scanf(" %c", &end);

        switch (end) {
        case 'Y':
            printf("\nOK!\n");
            break;
        default:
            printf("\nBYE!\n");
            break;
        }
    } while (end == 'Y');
    return 0;
}
brushtakopo
  • 1,238
  • 1
  • 3
  • 16
  • 4
    Unh... There are **TWO*** instances of `scanf()` in this code... You need to do more work... And, it's considered that a "good" answer is not just a "code dump" with no explanation of the OP's mistake/problem. – Fe2O3 Jan 10 '23 at 11:20
  • Nevermind adding `while ( getchar() != '\n' );` introduces the possibility of **another** infinite loop should `EOF` be reached before the next `\n` character is read. – Andrew Henle Jan 10 '23 at 12:13