How do I prevent this infinite loop?

Hello all,

I am working on a project for class. Here is the code:

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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include <stdio.h>
#include <ctype.h>

void DisplayApps(char *appPtr);
void SetCost(char app, double *appCostPtr);
void MoneyChoice(double *depositPtr, double appCost, double Account);
int Compare(double Account, double appCost); 
void GetChange(double Account, double appCost, double *acctPtr);
void AddDeposit(double Deposit, double Account, double *acctPtr);
void Again(char *quitPtr);

int main()
{
	char App='i'; char Quit='i';
	int YayOrNay=0; int Xfactor=0;
	double Account=0; double Deposit=0; double AppCost=0;

	printf("-----------Welcome to The App Store!-----------\n\n");

	do
	{
	DisplayApps(&App);

	SetCost(App, &AppCost);

	if(Account<AppCost)
	{
		do
		{
		MoneyChoice(&Deposit, AppCost, Account);
		AddDeposit(Deposit, Account, &Account);
		Compare(Account, AppCost);
		}
		while(Account<AppCost);
	}
	printf("Proceeding to check out...\n");

	GetChange(Account, AppCost, &Account);

	Again(&Quit);
	}
	while(Quit != 'n');

	printf("\n\nThank you for shopping at The App Store!\n\n\n");

	return 0;
}

void DisplayApps(char *appPtr)
{
	char Selection='i';
	do
	{
	printf("Here are the applications available.\n");
	printf("G: Graphing Calculator				$14.99\n");
	printf("M: Music Downloader				$1.99\n");
	printf("S: SAT Study Prep				$7.99\n");
	printf("T: TxtHelp					$4.99\n");
	printf("A: Astronomy Guide				$5.99\n\n");
	printf("Application to purchase: ");
	scanf(" %c", &Selection);
	Selection=tolower(Selection);
	}
	while(Selection != 'g' && Selection != 'm' && Selection != 's' && Selection != 't' && Selection != 'a' );
	*appPtr=Selection;
	return;
}

void SetCost(char app, double *appCostPtr)
{
	double Cost=0;

	switch (app)
	{
	case 'g':
		Cost=14.99;
		break;
	case 'm':
		Cost = 1.99;
		break;
	case 's':
		Cost=7.99;
		break;
	case 't':
		Cost= 4.99;
		break;
	case 'a':
		Cost= 5.99;
		break;
	default:
		printf("Error.");
		break;
	}

	*appCostPtr = Cost;
}

void MoneyChoice(double *depositPtr, double appCost, double Account)
{
	double DepOption=0; double Cost = appCost; int Selection=0;

	do
	{
	printf("\nYou currently have $%.2f in your account.", Account);
	printf("\nThe item you wish to purchase costs $%.2f.", appCost);
	printf("\n\nPlease select how much credit you wish to add towards your account.");
	printf("\n1>>		$15.00");
	printf("\n2>>		$10.00");
	printf("\n3>>		$5.00");
	printf("\n4>>		$2.00");
	printf("\n5>>		$1.00");
	printf("\n\nAmount to be added to account:  ");
	scanf(" %d", &Selection);
	}
	while (Selection != 1 && Selection != 2 && Selection != 3 && Selection != 4 && Selection != 5);
	
	switch (Selection)
	{
	case 1:
	DepOption = 15.00;
	break;
	case 2:
	DepOption=10.00;
	break;
	case 3:
	DepOption=5.00;
	break;
	case 4:
	DepOption=2.00;
	break;
	case 5:
	DepOption=1.00;
	break;
	default:
	printf("...Error...");
	break;
	}

	*depositPtr = DepOption;

	return;
}

void AddDeposit(double Deposit, double Account, double *acctPtr)
{
	double Combine=0;
	Combine = Deposit + Account;
	*acctPtr= Combine;
	return;
}

int Compare(double Account, double appCost)
{
	if (Account > appCost)
	{
		printf("\nYou now have enough money to purchase the app!\n");
		return 1;
	}
	else
	{
		printf("\nYou still do not have enough money for that purchase.\n");
		return 0;
	}
}

void GetChange(double Account, double appCost, double *acctPtr)
{
	double Change=0;
	Change = Account - appCost;
	*acctPtr = Change;
	printf("\nYour account now has $%.2f remaining after the purchase.", Change);
	return;
}

void Again (char *quitPtr)
{
	char QuitAnswer = 'i';
	do
	{
	printf("\n\nWould you like to continue shopping(y/n)? ");
	scanf(" %c", &QuitAnswer);
	}
	while(QuitAnswer != 'y' && QuitAnswer != 'n');
	*quitPtr = QuitAnswer;
	return;
}


As far as I can tell, the code only has one problem with it. When I call on MoneyChoice() and it displays the numerical options for the amount of money I wish to add to the account, if I enter a letter it goes into an endless loop. I have a similar safeguard in DisplayApps() that limits the user to only letter answers and if anything other than the letters sought after (including numbers) is entered, it simply reprints the options again without a problem and does not allow for any other input. I was wondering how I can also do this with MoneyChoice() as I only want the user to enter a #1-5 and anything else will not be accepted. Thanks for taking the time to look over my issue.
Have a look at this :

http://www.cplusplus.com/forum/beginner/104553/2/#msg564228


This has a separate ShowMenu function, and the logic is in the switch.

It also has while loops, which I much prefer over do loops.


I personally hate constructs like what you have on line 115, IMO they are error prone & not scalable.

With answers to questions (like on line 180), make use of the toupper function, and compare with 'Y' or 'N'. This makes the logic easier, and your code does not cope with the user entering either case (lower or upper)

Hope all goes well
Well, the issue here is that in DisplayApps(), the variable is a character. In MoneyChoice(), it is an int. When you input a number into a character variable, it simply puts the character of the number into the variable. Trying to stick a character into an int variable... isn't so clean. Rather, it causes an error with the input, then tries to read again. Thus trapping itself in an infinite loop.

http://www.gidnetwork.com/b-63.html provides great documentation on this exact issue, and the solution.
Last edited on
Topic archived. No new replies allowed.