Home > OS >  While loops and if and else statements not working as intended
While loops and if and else statements not working as intended

Time:11-13

I hope you're having a great day. Firstly, I would like to state that I am still a beginner to C and the coding world. I am working on a program that simulates a vending machine. This is done using while loops and if and else statements for the conditions and checks. I DO UNDERSTAND that my code is not optimized! I want to UNDERSTAND what I am reading in order for me to learn.

The vending machine program is roughly split into 4 parts. 1- Header 2-money loop 3-drink loop 4-exit loop

I am having a very hard time trying to piece it all together! When I fix one problem I run into another!

I am going to annotate my code in order to explain my thinking and then hopefully criticism is more effective.

`


#include <iostream>

using namespace std;

/*
    What I plan on using for conditions, etc.
*/
char orderCharacter;
char orderNumber;
float fundsAvailable = 0;
char moreMoney;
char moreDrinks;
bool quit = false;
bool quitTwo = false;


int main()
{
    /*
    simple header.
    */
    cout<<"========================================"<<endl;
    cout<<"Welcome to the Vending Machine"<<endl;
    cout<<"========================================"<<endl;

    /*
    While loop for inserting coins and bills. After user input, if and else output
    */
    while (quit == false){
    cout<<"Please insert your coins/bills"<<endl;
    cout<<"(1)$1, (2)$5, (3)$10, (4)$20 :"<<endl;
    cin>>orderNumber;

    if (orderNumber == '1'){
        fundsAvailable = fundsAvailable   1;
        cout<<"You've inserted: $1"<<endl;
        cout<<"Funds available: $"<<fundsAvailable<<endl;
        quit = true;
    }else if (orderNumber == '2'){
        fundsAvailable = fundsAvailable   5;
        cout<<"You've inserted: $5"<<endl;
        cout<<"Funds available: $"<<fundsAvailable<<endl;
        quit = true;
    }else if (orderNumber == '3'){
        fundsAvailable = fundsAvailable   10;
        cout<<"You've inserted: $10"<<endl;
        cout<<"Funds available: $"<<fundsAvailable<<endl;
        quit = true;
    }else if (orderNumber == '4'){
        fundsAvailable = fundsAvailable   20;
        cout<<"You've inserted: $20"<<endl;
        cout<<"Funds available: $"<<fundsAvailable<<endl;
        quit = true;
    }else{
        cout<<"Invalid Selection"<<endl;
        quit = false;
    }
//same process but for money...
    cout<<"Add more coins/bills? (Y/N): ";
    cin>>moreMoney;

    if ((moreMoney == 'N' || moreMoney == 'n') && (fundsAvailable>=1.50)){
            quit = true;
    }else if ((moreMoney == 'Y') || (moreMoney == 'y')){
            quit = false;
    }else if ((moreMoney == 'N' || moreMoney == 'n') && (fundsAvailable<=1.49)){
            cout<<"Insufficient funds to make a purchase."<<endl;
            cout<<"Please take your change."<<endl;
            quit = true;
            quitTwo = true;
            cout<<"Thank you for using our vending machine!"<<endl;
    }else{
            cout<<"Your answer is invalid. Please answer Y or N"<<endl;
            cout<<"Add more coins/bills? (Y/N): ";
            cin>>moreMoney;
        }
    }
//second while loop drink loop
    while (quitTwo == false){
        cout<<"Please make a selection:"<<endl;
        cout<<"(A)quaVeena $1.50, (B)epsi $2.00, (C)ool Cola $2.00, (G)atorade $2.25"<<endl;
        cin>>orderCharacter;

    if ((fundsAvailable <= 1.49) && (quitTwo == false)){
        cout<<"Insufficient funds to make a purchase."<<endl;
        cout<<"Please take your change."<<endl;
        cout<<"Thank you for using our vending machine!"<<endl;
    }
//calculations
    switch (orderCharacter){
        case 'A':{
        fundsAvailable = fundsAvailable - 1.50;
        break;
        }
        case 'a':{
        fundsAvailable = fundsAvailable - 1.50;
        break;
        }
        case 'B':{
        fundsAvailable = fundsAvailable - 2.00;
        break;
        }
        case 'b':{
        fundsAvailable = fundsAvailable - 2.00;
        break;
        }
        case 'C':{
        fundsAvailable = fundsAvailable - 2.00;
        break;
        }
        case 'c':{
        fundsAvailable = fundsAvailable - 2.00;
        break;
        }
        case 'G':{
        fundsAvailable = fundsAvailable - 2.25;
        break;
        }
        case 'g':{
        fundsAvailable = fundsAvailable - 2.25;
        break;
        }
}
    cout<<"Add more drinks (Y/N): ";
    cin>>moreDrinks;
//trying to checking available funds before selection, if lower than 1.50, automatically end and other options.
    if ((fundsAvailable >=1.50) && (moreDrinks == 'Y' || moreDrinks =='y')){
        quitTwo = false;
    }else if ((fundsAvailable <=1.49) && (moreDrinks == 'Y' || moreDrinks =='y')){
        quitTwo = true;
        cout<<"Funds available: $"<<fundsAvailable<<endl;
        cout<<"Please take your change."<<endl;
        cout<<"Thank you for using our vending machine!"<<endl;
    }else if ((fundsAvailable >=1.50) && (moreDrinks == 'N' || moreDrinks =='n')){
        quitTwo = true;
        cout<<"Funds available: $"<<fundsAvailable<<endl;
        cout<<"Please take your change."<<endl;
        cout<<"Thank you for using our vending machine!"<<endl;
    }else{
        cout<<"Your answer is invalid. Please answer Y or N"<<endl;
        cout<<"Add more drinks (Y/N): ";
        cin>>moreDrinks;
        quitTwo = false;
    }
}

    return 0;
}

`

I am having trouble mostly with drink loop as well as the exit loops. It is simple to have one loop with a condition or two. however I am having a hard time implanting all in sync. For example, if I click '2' for the first user input I have 5 dollars and purchase myself a gatorade for 2.25. the program will work as intended. however now if I make an invalid selection I will bypass the check for available funds. So even if I have 1 dollar, the vending machine will ask the user to make the selection (even though minimum is 1.50).

I know that my fundamentals of my code are lacking. I feel as if my loops aren't correctly stated or formed.

Known issues: Cant make invalid input more than once or code just skips ahead to next loop, fails to check conditions (this is an error of mine of course)

CodePudding user response:

You came to a point where you can choose between debugging your code and amending it. It may work, but it would break again at a certain point because it is too complicated. Or, you can refactor it.

Usually programmers would not hold all this logic (even if seems quite simple, it is not) in a single function, not to say a single loop. One may even think of tossing in a state machine to help. But even without a state machine the logic should be clearly separated into different operations.

In case you are not convinced that splitting the code to functions or at least into more than a single loop, play with the code a bit more, at a certain point I believe you would see it.

CodePudding user response:

Your code is very close to working correctly. There are a few issues that you need to fix in order to get it working as intended.

The first issue is in your while loop for adding coins/bills. You are setting the quit flag to true when the user enters a valid input (1, 2, 3, or 4). This means that the loop will only run once and the user will not be able to add more coins/bills. You need to remove this line:

quit = true;

The second issue is in your while loop for adding drinks. You are setting the quitTwo flag to false when the user enters a valid input (A, B, C, or G). This means that the loop will only run once and the user will not be able to add more drinks. You need to remove this line:

quitTwo = false;

The third issue is in your while loop for adding drinks. You are checking the fundsAvailable variable before the user makes a selection. This means that if the user has less than $1.50, they will not be able to make a selection. You need to move this check after the selection is made:

if ((fundsAvailable <= 1.49) && (quitTwo == false)){
        cout<<"Insufficient funds to make a purchase."<<endl;
        cout<<"Please take your change."<<endl;
        cout<<"Thank you for using our vending machine!"<<endl;
}

The fourth and final issue is in your while loop for adding drinks. You are setting the quitTwo flag to true when the user enters 'N' or 'n' for more drinks. This means that the loop will only run once and the user will not be able to add more drinks. You need to remove this line:

quitTwo = true;

I hope this helps!

CodePudding user response:

If fundsAvailable is less than 1.50 and the answer is n or N, your code returns a "invalid response" message. Shouldn't it be "please take your change" if the answer indicates no, irrespective of the change left? I think that's how vending machines work.

Whatever it may be, with your current code, I think it comes down to decimal imprecision. Whenever you do decimal operations in C , there will be decimal imprecision - so 0.1 will be 0.100000000000000132 or something, 0.5 will be 0.49999999999997562 or something (this is because of how decimals are represented in binary). Basically, in this case, fundsAvailable might not be exactly 1.5, but 1.4999999... or so. Thus, the condition fails, and you're left with an "invalid response" message.

So do something like

if (fundsAvailable > 1.5 || std::abs(fundsAvailable - 1.5) < threshold)
{
   //...
}

where threshold is a small value, such as 0.000001 or something. This should account for decimal imprecision.

In general, when comparing two floats for equality using ==, you're asking to get shot in the foot. C does not round decimals for you, so if there's decimal imprecision, you're screwed. Instead, check if the two values differ by a value less than threshold, which is a value of your choosing. This accounts for decimal imprecision, like I stated above.

  •  Tags:  
  • c
  • Related