Help with vending machine code

I can't seem to figure out what sort of an error is happening with my code. When I attempt to input my paidMoney variable, the if-elseif that comes next doesn't accurately interpret my input, and outputs either the wrong else-if, or starts looping indefinitely. I only started coding a couple of months ago, so I'm not quite sure whether the issue here is in my syntax, or if it's a logic error. My instructor isn't able to figure it out either, and I'd rather not redo everything, because I have a deadline and wouldn't be able to replicate it in time. Any help would be appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//
//  Vending Machine v0.4

//access c++ library
#include <iostream>
#include <iomanip>

//allows for the lack of the 'std' before cout and cin
using namespace std;

int main() {
        
    //this initializes the varriable for the 6 prices for the soda options
    float sodaPrices[6] = {2.50, 1.00, 2.00, 1.50, 2.50, 5.00};
    //this varbiable shows how many of each sodas are left in the vedning machine
    int sodaStock[6] = {3, 3, 3, 3, 3, 3};
    //this allows 6 individual types of soda to be declared
    char sodaTypes[6][12] = {"Moutain Dew", "Sprite", "Coca Cola", "Pepsi", "Water", "Root Beer"};
    
    //this variable stores the value for how much money is in the vending machine
    float currentMoney = 100;

    
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//INTERFACE TO SHOW YOU SODA OPTIONS

    //loop so the vending machine never stops working until out of stock
    while(sodaStock[0] != 0 && sodaStock[1] != 0 && sodaStock[2] != 0 && sodaStock[3] != 0 && sodaStock[4] != 0) {
        
 
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//VARIABLES THAT NEED TO BE REDEFINED EVERYTIME IT GOES BACK ON THE LOOP

        //choice for soda type
        int sodaChoice;
        //amount of money put into vending machine
        float paidMoney;
        //the amount of change you will recive
        float change;
        //whether or not you pay the right price
        char payOrNo;
        //final choice for purchasing soda
        char finalChoice;
        
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//MAIN MENU
        cout << "Welcome to to the vending machine\n";
        cout << "Here are your options for drinks:\n";
    
        //for loop to list all 6 soda types in order
        for (int i = 0; i < 6; i++)
            //lists the soda names and a number for each of them
            cout << i + 1 << ") " << sodaTypes[i] << "\n";

        
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//INTERFACE FOR PURCHASING SODA
    
        
        //asks you which soda you want to buy
        cout << "Which soda would you like to purchase (1-6)?\n";
        cin >> sodaChoice;
        sodaChoice = sodaChoice - 1;
        
        //if the soda isn't out of stock
        if (sodaStock[sodaChoice] > 0) {
        
            //confirmation for purchase
            cout << sodaTypes[sodaChoice] << " costs $" << sodaPrices[sodaChoice] << "\n";
            cout << "Would you like to purchase " << sodaTypes[sodaChoice] << " for $" << sodaPrices[sodaChoice] << "?(y/n) \n";
            cin >> finalChoice;
            
            //if they say they want to buy it
            if (finalChoice == 'y' || finalChoice == 'Y'){
                
                cout << "How much money would you like to pay with? $";
                cin >> paidMoney;
                cout << endl;
                
                
                //if they pay in exact change
                if (paidMoney == sodaPrices[sodaChoice]) {
                    //gets rid of 1 soda, and calculates how much money the vedning machine kept
                    sodaStock[sodaChoice]--;
                    currentMoney = currentMoney + sodaPrices[sodaChoice];
                    cout << "Thank your for your purchase";
                    system( "read -n 1 -s -p \"Press any button to enjoy your drink... \n \"" );
                }
                
                //if you paid more than enough money AND there is money in the machine
                else if (paidMoney > sodaPrices[sodaChoice]) {
                    change = paidMoney - sodaPrices[sodaChoice];
                    cout << "Youre change is $" << change;
                    //gets rid of 1 soda, and calculates how much money the vedning machine kept
                    sodaStock[sodaChoice - 1]--;
                    currentMoney = currentMoney + sodaPrices[sodaChoice];
                    currentMoney = currentMoney - change;
                    cout << "Thank your for your purchase";
                    system( "read -n 1 -s -p \"Press any button to enjoy your drink... \n \"" );
                }

                //if you dont pay enough
                else if (paidMoney < sodaPrices[sodaChoice]){
                    change = sodaPrices[sodaChoice - 1] - paidMoney;
                    cout << "Please give $" << change << " to complete payment for soda. (y/n)";
                    cin >> payOrNo;
                    
                    //if they dont want to pay enough
                    if (payOrNo == 'n' || payOrNo == 'N'){
                        cout << "Here is your money back";
                        currentMoney = currentMoney - paidMoney;
                        system( "read -n 1 -s -p \"Press any button go to main menu... \n \"" );
                        
                    }
                    
                    //if they want to pay enough
                    else if (payOrNo == 'y' || payOrNo == 'Y') {
                        //gets rid of 1 soda, and calculates how much money the vedning machine kept
                        sodaStock[sodaChoice]--;
                        currentMoney = currentMoney + sodaPrices[sodaChoice - 1];
                        cout << "Thank your for your purchase";
                        system( "read -n 1 -s -p \"Press any button to enjoy your drink... \n \"" );
                    }
                }
            }
            
            else if (finalChoice == 'n' || finalChoice == 'N') {
                system( "read -n 1 -s -p \"Press any button to restart system... \n \"" );
            }
        }
        
        //if you enter a wrong number
        else if (sodaChoice > 6){
            cout << "/nPlease enter a number between 1 and 6\n";
            system( "read -n 1 -s -p \"Press any button to retry... \n \"" );
        }
        
        //if the soda is out of stock
        else if (sodaStock[sodaChoice- 1] <= 0) {
            cout << "\nI'm sorry, we are out of stock for that soda.\n";
            system( "read -n 1 -s -p \"Press any button to select another soda... \n \"" );
        }
        
        //In case of error
        else {
            cout << "\nError\n";
            cout << "Please restart system";
        }
    }
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    cout << "\nI'm sorry, but we are currently out of everything.\n";
    cout << "Current money in vending machine: $" << currentMoney;
    
    //ends code (doesnt happend unless forced to)
    return 0
}
please do not use system for I/O. It works but is not a good habit to get into, use cin and cout.

floats often have trouble with exact matches. As do doubles. I highly recommend you convert your money to an integer format (for example in the united states, you would work with pennies as your integer base unit of 1 = 1 penny, 100 = 1 dollar, etc).

I suspect that is your problem. change paidmoney to double instead of float, and it will likely work most of the time. But integers/penny approach will work all the time.

I don't see anything else wrong with it. I would not put the declares inside that while loop (you can set them all back to zero if you want every loop iteration, but declare them outside the loop). But that isnt a real problem, its just a suggestion.
@jonnin
could you explain exactly how the system( "read -n 1 -s -p \"bla bla bla ... \n \"" ); works? i found it online because i needed help creating a way to wait for any input before continuing. Now I know how to use it and WHAT it does, but I have now idea as to HOW it works.

also, if you could suggest another way to do achieve this that would be better
Last edited on
Hello MrLostProphet,

jonnin makes some good points. If you are going to use a floating point type a "double" is preferred over the "float" as a "double" is more accurate then a "float, better precision.

You should compile your code before you post it you would have found out about the missing semi-colon.

When I made a choice of 1 this is what I got:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Welcome to to the vending machine
Here are your options for drinks:
1) Moutain Dew
2) Sprite
3) Coca Cola
4) Pepsi
5) Water
6) Root Beer
Which soda would you like to purchase (1-6)?: 1

Moutain Dew costs $2.50
Would you like to purchase Moutain Dew for $2.50 ?(y/n) y

How much money would you like to pay with? $1

Please give $-107374176.00 to complete payment for soda. (y/n)

Line 1 is meant to be blank.

You are good down to line 15. Your prompt ask "how much I would like to pay". Given this for a drink that costs $2.50 I would like to pay $1.00. You may want to consider something a little different.

Notice the rather large negative number on line 17. In your original code this comes from line 104. Your subscript is going out of range to -1 when "sodaChoice" is zero. Before I made an addition the number printed out was in scientific notation.

At line 44 I added cout << std::fixed << std::showpoint << std::setprecision(2);. This allows the output of floating point numbers to be non scientific notation. The "showpoint" will print ".00" in the output. The "setprecision(2)" is how many decimal places that will print.

In my short bit of testing that is what I have found so far,

Hope that helps,

Andy
Hello MrLostProphet,

It is best not to use "system" anything as it can be a problem.

That said what you really want is "system("pause");", but I generally use:
1
2
3
4
5
6
// <--- Used mostly for testing in Debug mode. Removed if compiled for release.
// <--- Used to keep the console window open in Visual Studio Debug mode.
// The next line may not be needed. If you have to press enter to see the prompt it is not needed.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
std::cout << "\n\n Press Enter to continue: ";
std::cin.get();
If the comments are not enough to make it work let me know.

jonnin may be able to explain how it works, but this is the first time I have seen it.

You are welcome to the above code and you can delete the comment is you want. Over time and looking for something to replace "system("pause")" I came up with this.

Hipe that helps,

Andy
@Handy Andy
Thanks for the suggestion,

I'm still very new to c++, and programming in general and am having trouble understanding the meaning on your code. The only part of std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); that I understand are the std: :cin and "\n". I have absolutely no idea clue what the rest off it means.

Also, I don't know what .get() does to a cin, in the code std::cin.get();
Hello MrLostProphet,

After a month or so of reading about how using namespace std; is a bad idea I started learning what is in the standard name space and how to qualify it.

The first thing you need to understand is that using using namespace std; in the global scope of the file means that when compiled the compiler tries to put "std::" in front of everything and if something you wrote, either a variable name or a function, happens to be in the standard name space it will put "std::" in front of it ans use what is in the standard name space and not what you wrote.

This is worth reading: http://www.cplusplus.com/doc/tutorial/namespaces/

Although it point is a bit different I would consider this a must read:
http://www.lonecpluspluscoder.com/2012/09/22/i-dont-want-to-see-another-using-namespace-xxx-in-a-header-file-ever-again/ Look closely at the parts about the using statements, i.e., "using std::cout" etc.

The statement "std::cin.ignore" is simple enough. Whether you use the "std::" or not the ".ignore" is a part of the "iostream" that you included. It may not come directly from "iostream", but from other header files that "iostream" includes.

Inside the () the first part, (std::numeric_limits<std::streamsize>::max(), '\n'), is just giving this a very large number. It could be replaced with "1000" or "100000 ". What is there is just using the largest number possible for your computer and compiler as header files have set for this.

The second part, (std::numeric_limits<std::streamsize>::max(), '\n'), is a character it looks for.

The whole thing together says to ignore characters in the input buffer up to this very large number or the new line character whichever comes first.

The nice thing about C++ is that you do not always have to know how something works right away just how to use it.

Read enough around here and you will see this or something like it quite often.

As far as the "std::" part I am just use to typing it without thinking and I nolonger use the line using namespace std; in my programs.

Hope that helps,

Andy
Hello MrLostProphet,

Sorry I missed the last question.

In simple terms the ".get()" is a member function of "cin". It allows you to just press "Enter" without typing anything else.

You can read about it here: http://www.cplusplus.com/reference/istream/istream/get/?kw=cin.get

Andy
Topic archived. No new replies allowed.