Returning to beginning of while loop halfway through?

I need help with part of a vending machine assignment.

If the user's chosen drink has run out, I want it to return to the beginning of the while loop instead of quitting, or going through the rest of the while loop (which is what it does right now), forcing the user to "enter money" even though their selected drink has run out. Theoretically, it should allow them to enter another choice, and then proceed through the loop. I tried using an if loop with the "continue" function but I don't think that was the right thing to do.

I think the rest of my code is correct besides this one error. Any pointers for this issue would be greatly appreciated! See my code below:

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

//structure for drink data
struct DrinkData
{
    string name[5]={"Cola","Root Beer","Lemon-Lime","Grape","Cream Soda"}; //array for drink names
    double price[5]={.75,.75,.75,.75,.75}; //array for drink costs
    int number[5]={20,20,20,20,20}; //array for number of drinks in machine
};

int main()
{   //declare variables
    DrinkData drink; //drink is a DrinkData structure.
    int choice; //for choice of drink
    float moneyReceived;
    float change;
    double earnings = 0.0;
    int quit=1;
    double totalearnings=0;
    
    while(quit==1) //THIS while loop is where I need help!
    {
    // Display a list of drinks preceded by a number. This will be the menu.
    cout << "\n 1. Cola:           .75 cents " << endl;
    cout << " 2. Root Beer:      .75 cents " << endl;
    cout << " 3. Lemon Lime:     .75 cents " << endl;
    cout << " 4. Grape Soda:     .75 cents " << endl;
    cout << " 5. Cream Soda:     .75 cents " << endl;
    cout << " Please select a drink by pressing on the corresponding number: ";
    cin>>choice;
        //input validation
        while(choice!=1 && choice!=2 && choice!=3 && choice!=4 && choice!=5)
        {cout<<"Please enter a valid choice, 1-5: ";
            cin>>choice;}
        //make sure there's enough cans
        if(drink.number[choice-1]==0)
        {cout<<"I'm sorry, we've run out of your selected drink. Please enter 2 to choose again: ";
            cin>>quit;} //I have them enter a value that isn't 1 (so the while loop should stop?), but it continues through...even though this message displays.
        
    //process money
    cout<<"Please enter an amount at most $1.00 to pay for your drink: ";
    cin>>moneyReceived;
        //input validation
        while(moneyReceived<0 || moneyReceived>1)
        {cout<<"Sorry, this vending machine does not accept money over $1.00. Please re-enter: ";
            cin>>moneyReceived;}
        //input validation
        while(moneyReceived<drink.price[choice-1])
        {cout<<"You did not enter enough to pay for your selection. Please re-enter: ";
            cin>>moneyReceived;}
            //dispense drink message, or process money
        cout<<"Your money is being processed. Your drink will be dispensed shortly.\n";
  
    //calculate change due
    change = moneyReceived - drink.price[choice-1];
    //update earnings
    earnings = moneyReceived - change;
    totalearnings = earnings + totalearnings;
    //decrease number of cans of selected drink in the machine
    drink.number[choice-1]=drink.number[choice-1]-1;
    //update user
        cout<<"Here is your change: "<<change<<". Thank you for purchasing a drink! \nIf you would like to purchase another one, please enter the value 1. If not, enter 0: ";
        cin>>quit;
    }
    
    cout<<"\nThe total earnings made by this vending machine has been "<<totalearnings<<" during this program.\n"<<endl;
    
    return 0;
}
Hello almostdone,

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
#include <iostream>
#include <iomanip>
#include<string>

//using namespace std;  // <--- Best not to use.
// The most recent post that is worth reading. http://www.cplusplus.com/forum/beginner/258335/

using std::cin;
using std::cout;
using std::endl;
using std::string;

constexpr size_t MAXSIZE{ 6 };

// structure for drink data
struct DrinkData
{
	string name[MAXSIZE] = { "", "Cola","Root Beer","Lemon-Lime","Grape","Cream Soda" }; //array for drink names
	double price[MAXSIZE] = { 0.0, 0.75, 0.75, 0.75, 0.75, 0.75 }; //array for drink costs
	int number[MAXSIZE] = { 0, 0,20,20,20 }; //array for number of drinks in machine
};

int main()
{   //declare variables
	DrinkData drink; //drink is a DrinkData structure.
	int choice; //for choice of drink
	float moneyReceived;
	float change;
	double earnings = 0.0;
	bool quit{};  // <--- Sets to (0) zero same as false.
	double totalearnings = 0;

	std::cout << std::fixed << std::setprecision(2);  // <--- Only needs done once unless something is changed.

	while (!quit) //THIS while loop is where I need help! Sets up an endless loop unless you want to end the program. Say when the machine is empty.
	{
		// Display a list of drinks preceded by a number. This will be the menu.
		cout << "\n 1. Cola:           .75 cents " << endl;
		cout << " 2. Root Beer:      .75 cents " << endl;
		cout << " 3. Lemon Lime:     .75 cents " << endl;
		cout << " 4. Grape Soda:     .75 cents " << endl;
		cout << " 5. Cream Soda:     .75 cents " << endl;
		cout << " Please select a drink by pressing on the corresponding number: ";
		cin >> choice;

		//input validation
		while (choice < 1 || choice > 5)
		{
			cout << "\n    Please enter a valid choice, 1-5.\n\n Enter choice: ";
			cin >> choice;
		}

		//make sure there's enough cans
		if (!drink.number[choice])  // <--- Any number greater than (0) zero is the same as true.
		{
			cout << "\n    I'm sorry, we've run out of your selected drink. Please select another.\n";
			//cin >> quit;
			continue;
		} //I have them enter a value that isn't 1 (so the while loop should stop?), but it continues through...even though this message displays.

First notice that the arrays are 1 larger and the first element is blank or "0.0" and the actual information starts at element 1. This saves you from writing if(drink.number[choice-1]==0). Now you do not need the "- 1" to line up with the arrays. The "0.0", or("0.75), is the more proper way to write a floating point number

The while loop and if statement have changed. They so the same as what you had just shorter.

In the if statement entering any number greater than (0) zero will end the for loop. At this point you want the first while loop to continue not end. Unless you have some idea I am not understanding. Ending the while loop should be done when all the product is sold or if you enter a special number for the menu choice, a number that is not listed.

The program works for the changes I have made. After that I have not looked at the rest.

Andy
That fixes my issue, thanks so much! I've never worked with Boolean data types before so I didn't even realize that was a possibility. I'll have to look more into that!

Thanks again
almostdone
Hello almostdone,

After working with the program I came up with this:
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
// Returning to beginning of while loop halfway through almostdone 269535
#include <cctype>  // <--- For "std::tolower()" and "std::toupper()".
#include <iostream>
#include <iomanip>
#include<string>

//using namespace std;  // <--- Best not to use.
// The most recent post that is worth reading. http://www.cplusplus.com/forum/beginner/258335/

using std::cin;
using std::cout;
using std::endl;
using std::string;

constexpr size_t MAXSIZE{ 6 };
constexpr int TOTALDRINKS{ 100 };

// structure for drink data
struct DrinkData
{
	string name[MAXSIZE] = { "", "Cola","Root Beer","Lemon-Lime","Grape","Cream Soda" }; //array for drink names
	double price[MAXSIZE] = { 0.0, 0.75, 0.75, 0.75, 0.75, 0.75 }; //array for drink costs
	//int number[MAXSIZE] = { 0, 20, 20, 20, 20, 20 }; //array for number of drinks in machine
	int number[MAXSIZE] = { 0, 0, 20, 20, 20, 20 };  // <--- Used for testing. Delete when finished.
};

int main()
{   
	//declare variables
	DrinkData drink; //drink is a DrinkData structure. You do not have to comment the incredibly obvious, the merely obvious will do. Unless it helps you then disregard.
	char yesNo{ 'Y' };  // <--- Added.
	int choice; //for choice of drink
	size_t totalDrinks{ 100 };  // <--- Added. Total drinks in the machine. Adjust to a smaller number for testing.
	double moneyReceived{};
	double change{};
	double earnings{};
	bool quit{};  // <--- Sets to (0) zero same as false.
	double totalearnings{};

	std::cout << std::fixed << std::setprecision(2);  // <--- Only needs done once unless something is changed.

	while (!quit) //THIS while loop is where I need help! Sets up an endless loop unlless you wnt to end the program. Say when the machine is empty.
	{
		if (totalDrinks == 0)
		{
			std::cout << "\n    The machine is empty.\n";

			quit = true;
			continue;
		}

		// Display a list of drinks preceded by a number. This will be the menu.
		cout << "\n 1. Cola:           .75 cents " << endl;
		cout << " 2. Root Beer:      .75 cents " << endl;
		cout << " 3. Lemon Lime:     .75 cents " << endl;
		cout << " 4. Grape Soda:     .75 cents " << endl;
		cout << " 5. Cream Soda:     .75 cents " << endl;
		cout << " Please select a drink by pressing on the corresponding number: ";
		cin >> choice;

		//input validation
		while (choice < 1 || choice > 5)
		{
			cout << "\n    Please enter a valid choice, 1-5.\n\n Enter choice: ";
			cin >> choice;
		}

		//make sure there's enough cans
		if (!drink.number[choice])  // <--- Any number greater than (0) zero is the same as true.
		{
			cout << "\n    I'm sorry, we've run out of your selected drink. Please select another.\n";
			//cin >> quit;  // <--- You could use this, but it is better to start the loop over.
			continue;
		}

		//process money
		cout << "\n Please enter an amount at most $1.00 to pay for your " << drink.name[choice] << " drink: ";
		cin >> moneyReceived;

		//input validation
		while (/*moneyReceived < 0 ||*/ moneyReceived > 1)
		{
			cout << "\n    Sorry, this vending machine does not accept money over $1.00. Please re-enter: ";
			cin >> moneyReceived;
		}
		//input validation
		while (moneyReceived < drink.price[choice])
		{
			double additionalMoney{};

			cout << "\n    You did not enter enough to pay for your selection. Please add: " << drink.price[choice] - moneyReceived << ": ";
			cin >> additionalMoney;

			moneyReceived += additionalMoney;
		}
		//dispense drink message, or process money
		cout << "\n  Your money is being processed. Your drink will be dispensed shortly.\n";

		//calculate change due
		change = moneyReceived - drink.price[choice];

		//update earnings
		earnings = moneyReceived - change;

		totalearnings = earnings + totalearnings;  // <--- totalEarnings += earbubgs; does the same.

		//decrease number of cans of selected drink in the machine
		drink.number[choice]--;  // <--- Does the same as what you have just simpler.
		totalDrinks--;

		//update user
		cout << "\n  Here is your change: " << change << ". Thank you for purchasing a drink!"
			"\n\n If you would like to purchase another one, please enter (Y or N): ";
		cin >> yesNo;
		
		if (std::toupper(yesNo) == 'N')  // <---Added.
			break;
	}

	cout
		<< "\n The total earnings made by this vending machine has been " << totalearnings
		<< " during this program.\n"
		<< "\n With a total of " << TOTALDRINKS - totalDrinks << " drinks sold."
		<< endl;

	return 0;
}

I tried to make the program more like a real vending machine, but it is still possible that it could be improved on.

I did find that the number array was 1 element short.

I do have one problem with "totalearnings". It is not really a correct value. I am think more like: groseEarnings = (products sold * price) - (products sold * wholesale cost);. Then from that subtract any other expenses to get net profit or netEarnings.

May not be a big thing, but something to consider.

This is just part of a test run I did:

 1. Cola:           .75 cents
 2. Root Beer:      .75 cents
 3. Lemon Lime:     .75 cents
 4. Grape Soda:     .75 cents
 5. Cream Soda:     .75 cents
 Please select a drink by pressing on the corresponding number: 0

    Please enter a valid choice, 1-5.

 Enter choice: 4

 Please enter an amount at most $1.00 to pay for your Grape drink: 1.0

  Your money is being processed. Your drink will be dispensed shortly.

  Here is your change: 0.25. Thank you for purchasing a drink!

 If you would like to purchase another one, please enter (Y or N): b


 1. Cola:           .75 cents
 2. Root Beer:      .75 cents
 3. Lemon Lime:     .75 cents
 4. Grape Soda:     .75 cents
 5. Cream Soda:     .75 cents
 Please select a drink by pressing on the corresponding number: 2

 Please enter an amount at most $1.00 to pay for your Root Beer drink: .75

  Your money is being processed. Your drink will be dispensed shortly.

  Here is your change: 0.00. Thank you for purchasing a drink!

 If you would like to purchase another one, please enter (Y or N): 3

 1. Cola:           .75 cents
 2. Root Beer:      .75 cents
 3. Lemon Lime:     .75 cents
 4. Grape Soda:     .75 cents
 5. Cream Soda:     .75 cents
 Please select a drink by pressing on the corresponding number: 5

 Please enter an amount at most $1.00 to pay for your Cream Soda drink: .5

    You did not enter enough to pay for your selection. Please add: 0.25: .05

    You did not enter enough to pay for your selection. Please add: 0.20: .2

  Your money is being processed. Your drink will be dispensed shortly.

  Here is your change: 0.00. Thank you for purchasing a drink!

 If you would like to purchase another one, please enter (Y or N): n

 The total earnings made by this vending machine has been 3.00 during this program.

 With a total of 4 drinks sold.


When you get to the line If you would like to purchase another one, please enter (Y or N): 3. Anything other than "n" or "N" will continue the while loop.

I am not saying it is perfect or the best way to do this, but see what you think.

Andy
You made some wonderful additions, thanks so much!

Maybe it could be improved upon as you said, but I don't think I can do much after your additions. One (very small) thing I have changed is to make the menu say "75 cents" instead of "".75 cents," as that's technically incorrect.

Other than that, I think you made it a great code. Thanks again!
Hello almostdone,

Any time.Glad it worked out for you.

Andy
Topic archived. No new replies allowed.