[solved] do while loop runs correctly once

I've got the following code which works right the first time through the do while loop which encompasses the main part of the program. The problem is that after you tell it you would like to enter another set of data it skips most user input & goes directly to the output with no numbers in it & then asks if you want to enter another set of data. I can't seem to figure out what went wrong that causes this to work correctly the first time, but not the second.

I'm a complete noob to programming, so be gentle, I know my code is ugly... 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
157
158
159
160
161
162
163
164
165
166
167
// Window_replacement_calc

#include <cctype>
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <stdlib.h>
using namespace std;

bool validate (const string& s)
{
for (unsigned int j = 0; j < s.length(); j++)
	{
	if (!isdigit(s[j]))
		{
		return false;
		}
	}
return true;
}


int main()
{

int nWindows, i, temp, totlabor, totdiscount, totcharges, accountnumber=1000;
double discount, total = 0.0;
char cont='y';
string strWindows;

do
{
	while (1)
	{
		nWindows=0;
		strWindows="";
		cout << "Enter the number of windows you would like to replace: ";
		getline(cin,strWindows); 
		
		if (validate(strWindows))
		{
			stringstream strStream;
			strStream << strWindows;
			strStream >> nWindows;
			cout <<"\n";
			break;
		}

		else
		{
		cout<<"\n\n\nDoes \""<<strWindows<<"\" look like a number of Windows?"<<endl;
		cout<<"You can't sneak your sneaky invalid data by me sucka, I'm checking for that"<<endl;
		cout<<"So don't even try it"<<endl;
		continue;
		}
	}

	//lets set the labor discount based on the # of windows that are being replaced
	if (nWindows > 10)
		discount=0.15;
	else if (nWindows >= 5)
		discount=0.075;
	else
		discount=0.0;

	//This dynamically sets the array up with dimensions of nWindows rows and 2 columns
	int * WindowLength = new int[nWindows];
	int * WindowWidth = new int[nWindows];
	double * WindowPrice = new double[nWindows];

	for (i=0; i < nWindows; i++)
	{	
		WindowLength[i]=0;
		WindowWidth[i]=0;
	}

	//lets get user input on length and width of each window, validate, and store it
	for (i=0; i<nWindows; i++)
	{
		while (1)
		{
			cout << "Enter the Length of window " << (i+1) <<" (whole inches only): ";
			string strWindows;
			getline(cin,strWindows);
			if (validate(strWindows))
			{
				stringstream strStream;
				strStream << strWindows;
				strStream >> temp;
				WindowLength[i]=temp;
				break;
			}
			else
			{
			cout<<"\n\n\nDoes \""<<strWindows<<"\" look like a valid Length?"<<endl;
			cout<<"You can't sneak your sneaky invalid data by me sucka, I'm checking for that"<<endl;
			cout<<"So don't even try it"<<endl;
			continue;
			}
		}
	while (1)
		{
		cout << "Enter the Width of window " << (i+1) <<" (whole inches only): ";
		string strWindows;
		getline(cin,strWindows);
		if (validate(strWindows))
			{
			stringstream strStream;
			strStream << strWindows;
			strStream >> temp;
			WindowWidth[i]=temp;
			cout <<"\n";
			break;
			}
		else
			{
			cout<<"\n\n\nDoes \""<<strWindows<<"\" look like a valid Width?"<<endl;
			cout<<"You can't sneak your sneaky invalid data by me sucka, I'm checking for that"<<endl;
			cout<<"So don't even try it"<<endl;
			continue;
			}
		}
	}

	cout <<"\n\n"<<endl;

	//sets the values in the WindowPrice array to correct values
	for (i=0; i<nWindows; i++)
	{
		temp=(WindowLength[i]+WindowWidth[i]);
		if (temp>140)
			WindowPrice[i]=184.95;
		else if (temp >= 100)
			WindowPrice[i]=164.95;
		else if (temp >= 80)
			WindowPrice[i]=134.95;
		else
			WindowPrice[i]=114.95;
	cout <<"A "<<WindowLength[i]<<" by "<<WindowWidth[i]<<" window will cost you "<<WindowPrice[i]<<endl;
	total=total+WindowPrice[i];
	}

	totlabor = int (100*((nWindows * 95.95)+.005));
	totdiscount = int (100*((discount*95.95*nWindows)+.005));
	totcharges = int (100*(((95.95*(1-discount)*nWindows)+total)+.005));

	cout <<"\naccount number "<<accountnumber<<endl;
	cout <<"*************************************************"<<endl;
	cout <<"Total cost of windows:\t$"<<total<<endl;
	cout <<"Total labor charges:\t$"<<totlabor/100<<"."<<totlabor%100<<endl;
	cout <<"Labor discount applied:\t$"<<totdiscount/100<<"."<<totdiscount%	100<<endl;
	cout <<"Total charges:\t\t$"<<totcharges/100<<"."<<totcharges%100<<endl;


	cout <<"\n\n\nWould you like to enter another quote? (Y or N)"<<endl;
	cin >> cont;

	delete [] WindowLength;
	delete [] WindowWidth;
	delete [] WindowPrice;
	accountnumber++;
} while (cont == 'y' || cont == 'Y');

cout <<"\nThank you for getting a quote from xyz construction, Goodbye"<<endl;
return 0;
}



Here is a sample run from the program... note that after I tell the program I would like to continue I don't enter any data.

Enter the number of windows you would like to replace: 3

Enter the Length of window 1 (whole inches only): 15
Enter the Width of window 1 (whole inches only): 89

Enter the Length of window 2 (whole inches only): 24
Enter the Width of window 2 (whole inches only): 45

Enter the Length of window 3 (whole inches only): 12
Enter the Width of window 3 (whole inches only): 15




A 15 by 89 window will cost you 164.95
A 24 by 45 window will cost you 114.95
A 12 by 15 window will cost you 114.95

account number 1000
*************************************************
Total cost of windows: $394.85
Total labor charges: $287.85
Labor discount applied: $0.0
Total charges: $682.70



Would you like to enter another quote? (Y or N)
y
Enter the number of windows you would like to replace:




account number 1001
*************************************************
Total cost of windows: $394.85
Total labor charges: $0.0
Labor discount applied: $0.0
Total charges: $394.85



Would you like to enter another quote? (Y or N)
Last edited on
-- EDIT --

nevermind what I had here before -- your indentation threw me off and I mismatched everything

EDIT AGAIN

I don't do much console work, but iirc using getline as well as 'cin >>' is problematic because of some weird buffering issue I don't fully understand. I think in order to do this you need to reset the input buffer somehow. After checking the documenation it looks like sync() does just that.

Try throwing cin.sync(); just before cin >> cont;. And also before your getline call. Maybe that will fix your problem.
Last edited on
Poor indenting on my part... let me go back & change it so its clearer.

The first do actually encompasses much of the program & is the control I'm using to say "do this stuff" , "would you like to do it again?"

The while (1) loop is an infinite loop to receive user input then break once valid data is received.
Yeah sorry about my original post. Didn't look closely enough at the code.

I edited my post with what I suspect might be the problem. But you replied before I finished editing =x, so I'm replying now mainly so the topic gets marked as 'new' and you see it.
Just modified the wierd indentation to try to get it to match a bit better. Trying your cin.sync idea now.
I dropped cin.sync(); before all getline & cin calls... it works like a charm... I had run across resetting the input buffer before in some input handling documentation, but I must have just glossed over it.

Code is still ugly, but at least its now functioning ugly code :-)

I'm going to attempt to break this down into logical functions at a minimum now that it works.

Thank you Disch, you rock!
Last edited on
closed account (z05DSL3A)
This may be worth a read
Using cin to get user input.:
http://www.cplusplus.com/forum/articles/6046/
I read through Grey Wolf's suggestion after sleeping on this... cin.sync() solves my "problem" ... but changing the code to use getline throughout causes there to be no problem needing solving in the first place because the wierd buffering issue never gets a chance to take place without my mixing of cin & getline.

So I got rid of the cin.sync()'s & replaced my use of cin with another getline... problem is even more solved now than before... and I get the added bonus of now having semi-validated/checked-for-nonsense input.
Last edited on
Here was the final code if anyone is interested.

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
188
189
190
// Window_replacement_calc

#include <cctype>
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <stdlib.h>
using namespace std;
//checks to make sure that input (entered as a string) is a valid integer
bool ValidateInt (const string& s)
{
	for (unsigned int j = 0; j < s.length(); j++)
	{
		if (!isdigit(s[j]))
		{
			return false;
		}
	}
	return true;
}
//takes a string & returns it as an int after validation has been confirmed
int ReturnInt (const string& t)
{
	int rtrn=0;
	stringstream strStream;
	strStream << t;
	strStream >> rtrn;
	return rtrn;
}
//end of header & function definitions
int main()
{
	//temp is a temporary variable 
	//totdiscount is the total discount
	//totlabor is the total labor without no discount
	//totcharges is the total charges after discount
	//accountnumber arbitrarily begins at 1000 and increments by 3... any value could be set here
	//i will be reused as our looping counter
	//nWindows is the number of windows being quoted
	unsigned int nWindows, i, temp, totlabor, totdiscount, totcharges, accountnumber=1000;

	//discount is calculated based on the number of windows needing replacement
	//total is the individual window prices (based on calculated dimensions) added together with no discount applied
	double discount, total = 0.0;

	//cont is a control variable to determine if another quote should be run
	//strWindows is a receiver variable for all user input
	char cont='y';
	string strWindows;

	do
	{
		//Find out how many windows need to be replaced, validate data, store it for future use
		while (1)
		{
			cout << "enter the number of windows you would like to replace: ";
			getline(cin,strWindows); 
			if (ValidateInt(strWindows) && strWindows.length() >= 1)
			{
				nWindows=ReturnInt(strWindows);
				cout <<"\n";
				break;
			}
			else
			{
				cout<<"\n\n\n\""<<strWindows<<"\" is not a valid whole number"<<endl;
				cout<<"Please ";
				continue;
			}
		}
		//set the labor discount based on the # of windows that are being replaced
		if (nWindows > 10)
			discount=0.15;
		else if (nWindows >= 5)
			discount=0.075;
		else
			discount=0.0;
		//This sets up dynamic arrays with nWindows elements... it may be slightly excessive to use dynamic arrays here
		//but I did this to allow further development of this code in the future without further modifications
		int * WindowLength = new int[nWindows];
		int * WindowWidth = new int[nWindows];
		double * WindowPrice = new double[nWindows];
		for (i=0; i < nWindows; i++)
		{	
			WindowLength[i]=0;
			WindowWidth[i]=0;
		}
		//gets user input on length and width of each window, validates data, and stores it for nWindows elements in dynamic arrays
		for (i=0; i<nWindows; i++)
		{
			while (1)
			{
				cout << "Enter the Length of window " << (i+1) <<" (whole inches only): ";
				string strWindows;
				getline(cin,strWindows);
				if (ValidateInt(strWindows) && strWindows.length() >= 1)
				{
					WindowLength[i]=ReturnInt(strWindows);
					break;
				}
				else
				{
					cout<<"\n\n\n\""<<strWindows<<"\" is not a valid Length"<<endl;
					cout<<"Please ";
					continue;
				}
			}
			while (1)
			{
				cout << "Enter the Width of window " << (i+1) <<" (whole inches only): ";
				string strWindows;
				getline(cin,strWindows);
				if (ValidateInt(strWindows) && strWindows.length() >= 1)
				{
					WindowWidth[i]=ReturnInt(strWindows);
					cout <<"\n";
					break;
				}
				else
				{
					cout<<"\n\n\n\""<<strWindows<<"\" is not a valid Width"<<endl;
					cout<<"Please ";
					continue;
				}
			}
		}
		cout <<"\n\n"<<endl;
		//print formatted output from data entry
		//sets the values in the WindowPrice array to correct values
		cout <<"******************************************************************"<<endl;
		cout <<"******************************************************************"<<endl;
		cout <<"******************************************************************"<<endl;
		cout <<""<<left<<setw(28)<<"****"<<left<<"Order Summary"<<right<<setw(25)<<"****"<<endl;
		cout <<""<<left<<setw(25)<<"****"<<left<<"Account Number "<<accountnumber<<right<<setw(22)<<"****"<<endl; 
		cout <<"******************************************************************"<<endl;
		for (i=0; i<nWindows; i++)
		{
			temp=(WindowLength[i]+WindowWidth[i]);
			if (temp>140)
				WindowPrice[i]=184.95;
			else if (temp >= 100)
				WindowPrice[i]=164.95;
			else if (temp >= 80)
				WindowPrice[i]=134.95;
			else
				WindowPrice[i]=114.95;
			cout <<""<<left<<setw(10)<<"****     A"<<right<<setw(6)<< WindowLength[i] <<" by "<<left<<setw(6)<< WindowWidth[i] <<" window will cost you "<<setw(8)<<WindowPrice[i]<<right<<setw(10)<<"****"<<endl;
			total=total+WindowPrice[i];
		}
		//Run calculations for totals before output
		//To assure 2 digit precision (aka whole cents only) and simple rounding <=.5 cents rounds up, >.5 cents rounds down
		//we are using floating point calculations, multiplying it by 100, adding .005
		//and casting the floating point result to an integer
		totlabor = int (100*((nWindows * 95.95)+.005));
		totdiscount = int (100*((discount*95.95*nWindows)+.005));
		totcharges = int (100*(((95.95*(1-discount)*nWindows)+total)+.005));
		//Results of all data entry
		//Seperating the variables that we just finished calculating into readable
		//dollars and cents is done using division & the modulus operator
		cout <<"******************************************************************"<<endl;
		cout <<""<<left<<setw(17)<<"****"<<left<<setw(26)<<"Total cost of windows:"<<right<<setw(11)<<total<<right<<setw(12)<<"****"<<endl;
		cout <<""<<left<<setw(17)<<"****"<<left<<setw(26)<<"Total labor charges:"<<right<<setw(8)<<totlabor/100<<setw(1)<<"."<<setw(2)<<totlabor%100<<right<<setw(12)<<"****"<<endl;
		cout <<""<<left<<setw(17)<<"****"<<left<<setw(26)<<"Labor discount applied:"<<right<<setw(8)<<totdiscount/100<<setw(1)<<"."<<setw(2)<<totdiscount%100<<right<<setw(12)<<"****"<<endl;
		cout <<""<<left<<setw(17)<<"****"<<left<<setw(26)<<"Total charges:"<<right<<setw(8)<<totcharges/100<<setw(1)<<"."<<setw(2)<<totcharges%100<<right<<setw(12)<<"****"<<endl;
		cout <<"******************************************************************"<<endl;
		cout <<"******************************************************************"<<endl;
		cout <<"******************************************************************"<<endl;
		//Find out if the user would like to get another quote, validate entry, and loop as needed
		while (1)
		{
			cout <<"\n\n\nWould you like to enter another quote? (Y or N)"<<endl;
			getline(cin, strWindows);
			if (strWindows.length() == 1 && (strWindows[0] == 'y' ||strWindows[0] == 'Y' || strWindows[0] == 'n' ||  strWindows[0] == 'N')) 
			{
				cont = strWindows[0];
				break;
			}
		}
		//clears space used by dynamic arrays
		delete [] WindowLength;
		delete [] WindowWidth;
		delete [] WindowPrice;
		//increments account number - doing so by 3 is arbitrary
		accountnumber+=3;
	} while (cont == 'y' || cont == 'Y');
	//End of program
	cout <<"\nThank you for getting a quote from xyz construction, Goodbye"<<endl;
	return 0;
}
Topic archived. No new replies allowed.