printing linked list

I have a linked list that I am trying to print out part of a movie theatre POS system for sold tickets. I made a class(Sale) that holds all my data for the number of seats, price, and transaction number. I made another class(searchList) that I made my own linked list to store all the objects that I create in my main program. I can search and find an object with no problem but when I try and print out all the nodes I have been getting tons of errors. I have tried overloading the insertion, dereferencing, I was even trying to make a friend iterator as well and haven't been able to figure it out. I will post the pieces of the code I think is the most pertinent, I don't want to post everything(some people don't like it). Any help would be great, thank you!

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
//this is my linked list class 
//display of list
		void display();
template<class T>
void SearchList<T>::display() 
{
	
	cout << "History:";

	/*for (Node<T> *traverseP = frontP;
		traverseP != NULL;
		traverseP = traverseP->nextP)
		cout << " " << *(traverseP);*/
	
	Node<T> traverseP = frontP;
	while (traverseP)
	{
		cout << traverseP->info;
		traverseP = traverseP->nextP;
	}

}

  private:
		template<class T>
		struct Node {
			
			T info;

			Node<T> *nextP;
		};

		//front of my list
		Node<T> *frontP;

		//keep track of the rear for easy insertion
		Node<T> *rearP;

//inside my main
//sale record
	//is of type sale to access sale class
	SearchList<Sale> sold;

//add new sale
				Sale newSale;
				newSale.setTrans(size,transaction,totalticketsale);

				sold.add(newSale);
sold.display();

Hello JayGln,

Your poses many questions:

Is this an assignment about linked lists or could you use something different?

Why the linked list of "SearchList"?

but when I try and print out all the nodes I have been getting tons of errors.

My answer to that is 42 https://www.youtube.com/watch?v=aboZctrHfK8

After watching the video, saying that you have tons of errors does not mean much without posting the full error message. Most times when you fix the first errors listed many of the others will go away.

The function looks like it should work, but I have no idea what traverseP->info is.

A thought I had is that by adding a variable to the class "Sales" you could eliminate the need for the linked list "SearchList". Also thinking that a "vector" of type "Sales" may be a better choice than a linked list.

You wrote:
I will post the pieces of the code I think is the most pertinent, I don't want to post everything(some people don't like it).

The problem here is that what you think is the most pertinent may not be where the problem starts.

Lines 24 - 37 do not tell me what class they are a part of and when you give "T" a value what is it?

If "T" refers to a class and "T info;" defines an object of a class then "cout << traverseP->info;" is trying to print an object of a class and not a variable. In this case the insertion operator (<<) needs to be overloaded to print the necessary information from the class.

It is probably me, but the full definition of the classes would help so I can see what you are doing with them. Even the full program that I could compile and test sometimes works better for me.

Hope that helps for now,

Andy
Thank you Andy,
This is my final project for my data structures and algorithms class to graduate. All structures and implementations of everything is what my professor told me to fix when I saw him friday. My traverseP is my traversal pointer that is assigned from my front pointer, info(data) and nextP(linking pointer to next node). I will post all the code but I warned you I have three classes and files(sales(for my base object), searchList(is for my linked list), Queue(for my line), and my main). I tried posting everything but it was too long so I will post by file(.h and .cpp ) together.

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
//sale class

class  Sale {
	

public:

	//constructor
	Sale();
	Sale(int items, int transNum, double transToatal);

	//copy constructor

	//assingment

	//accessors
	double getTotal() const;
	int getTransNum() const;
	int getItemCount() const;

	void setTrans(int items, int transNum, double transToatal);
	

	void outPut() const;

	//int findTrans(const SearchList &transNum1, const SearchList &transNum2);

private:
	//for the each item
	int items;

	//transaction number (unique identifier)
	int transNum;

	//total for the transaction
	double transTotal;

	
};

// Equality operator so that products can be compared.
bool operator ==(const Sale &prod1,
	const Sale &prod2);
// Postcondition: Compare as equal if have same id.

// Less than operator so that products can be compared.
bool operator <(const Sale &prod1,
	const Sale &prod2);
// Postcondition: Compare as less than if id of first is
// less than id of second.


Sale::Sale() {

	//initailize variable
	transNum = 0;
	transTotal = 0.0;
	items = 0;
}

Sale::Sale(int itemCount, int newTransNum, double newTransTotal)
{

	items = itemCount;
	transNum = newTransNum;
	transTotal = newTransTotal;

	//using set to make sure that the values are valid
	//setTrans(items, transNum, transTotal);

}


double Sale::getTotal() const
{
	return transTotal;
}

int Sale::getTransNum() const
{
	return transNum;
}

int Sale::getItemCount() const
{
	return items;
}

void Sale::setTrans(int itemCount, int newTransNum, double newTransTotal)
{
	items = itemCount;
	transNum = newTransNum;
	transTotal = newTransTotal;
}

void Sale::outPut() const
{
	//transaction header
			cout << "********************" << endl;
			cout << "*Tranaction Summary*" << endl;
			cout << "********************" << endl;

			cout << "Transaction Number: " << transNum << endl;
			cout << "Transaction Total:  " << transTotal << endl;
			cout << "Seats sold:         " << items << endl;
			

}



bool operator==(const Sale & prod1, const Sale & prod2)
{
	return prod1.getTransNum() == prod2.getTransNum();
}

bool operator<(const Sale & prod1, const Sale & prod2)
{
	return prod1.getTransNum() < prod2.getTransNum();
}




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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
//searchList
template<class T>
class SearchList
{
	public:

		//constructor
		SearchList();

		//copy constructor
		SearchList(const SearchList &otherSale);

		//overloaded assignment
		SearchList<T> &operator =(
			const SearchList &otherSale);


		//destructor
		~SearchList();

		// Determine emptiness or fullness
		bool isEmpty() const;
		bool isFull() const;

		// See value at front
		//void front() const;

		// Add value to rear
		 void add(const T &item);

		// Remove value at front
		//T remove();

		bool find(T &searchElement) const;

		//display of list
		void display();
		 

	private:
		template<class T>
		struct Node {
			
			T info;

			Node<T> *nextP;
		};

		//front of my list
		Node<T> *frontP;

		//keep track of the rear for easy insertion
		Node<T> *rearP;


		void clear();
		void append(const SearchList<T> &otherList);

};


template<class T>
 SearchList<T>::SearchList()
{

	frontP = NULL;  // initially empty
	rearP = NULL;
}


// Copy constructor

 template<class T>
 SearchList<T>::SearchList(const SearchList<T> &otherList)
{
	frontP = NULL;  // initially empty
	rearP = NULL;

	// Append elements from other Sale.
	append(otherList);
}

// Destructor

 template<class T>
 SearchList<T>::~SearchList()
{
	clear();  // empty list
}

// Assignment operator
 template<class T>
SearchList<T> &SearchList<T>::operator =(
	const SearchList<T> &otherSale)
{
	// Avoid copying if assigning object to self.
	if (this != &otherSale)
	{
		// Copy non-dynamic array members (none here).

		// Remove current nodes, reset pointer.
		clear();

		// Append elements from other Sale.
		append(otherSale);
	}

	// Return self.
	return *this;
}



// Accessors

template<class T>
bool SearchList<T>::isEmpty() const
{
	return frontP == NULL;
}

template<class T>
bool SearchList<T>::isFull() const
{
	// Linked list never full since can add more
	// nodes (though could run out of memory).
	return false;
}





//
// void Sale::front() const
//{
//	if (frontP == NULL)
//	{
//		cerr << "Sale empty: no element at front" << endl;
//		return;
//	}
//
//	return frontP->info;
//}

// Mutators

// Add value to rear
template<class T>
void SearchList<T>::add(const T &item)
{
	// Allocate new node 
	Node<T> *newNodeP = new Node<T>;

	//store data in the new node
	newNodeP->info = item;
	
	//new nodes will be added at the end
	newNodeP->nextP = NULL;  // none after this node

	//start list if it is empty
	if (frontP == NULL)
	{
		//sets front and rear to new nodes position
		frontP = rearP = newNodeP;
	}
	else
	{
		//point the old rear to new node
		rearP->nextP = newNodeP;

		//set rear to new node
		rearP = newNodeP;
	}
}

// Remove value at front
//template<class T>
//T SearchList<T>::remove() 
//{
//	if (frontP == NULL)
//	{
//		cerr << "Sale empty: cannot delete element" << endl;
//		return T();
//	}
//
//	// Advance front pointer and deallocate node.
//	Node *deleteP = frontP;
//	frontP = frontP->nextP;
//	delete deleteP;
//
//	if (frontP == NULL)  // removed the only node
//		rearP = NULL;
//}

//displays the transaction summary
template<class T>
bool SearchList<T>::find(T &searchValue) const//change to find, renamer , paramet
{
		for (Node<T> *traverseP = frontP; traverseP != NULL; traverseP = traverseP->nextP)
		{
			// PERFORM LINEAR SEARCH OF LINKED LIST TO FIND VALUE.
				if (traverseP->info == searchValue)
				{
					searchValue = traverseP->info;
					return true;
				}
		}
	
	return false;
}

template<class T>
void SearchList<T>::display() 
{
	
	cout << "History:";

	/*for (Node<T> *traverseP = frontP;
		traverseP != NULL;
		traverseP = traverseP->nextP)
		cout << " " << *(traverseP);*/
	
	Node<T> traverseP = frontP;
	while (traverseP)
	{
		cout << traverseP->info;
		traverseP = traverseP->nextP;
	}

}





template<class T>
void SearchList<T>::clear()
{
	while (frontP != NULL)
	{
		// Keep temporary pointer to node about
		// to delete.
		Node<T> *deleteP = frontP;

		// Advance to next node.
		frontP = frontP->nextP;

		// Deallocate node.
		delete deleteP;
	}

	// After loop, frontP is NULL.  Set rearP
	// to NULL also.
	rearP = NULL;
}

template<class T> 
void SearchList<T>::append(const SearchList<T> &otherSale)
{
	for (Node *traverseP = otherSale.frontP; traverseP != NULL; traverseP = traverseP->nextP)
	{
		addRear(traverseP->items, traverseP->transNum, traverseP->transTotal);

	}
		
}
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
//queue class
template <class T>
class Queue
{
public:
	// Constructors
	Queue(int size);  // initial capacity

	// Copy constructor
	Queue(const Queue<T> &otherQueue);

	// Assignment operator
	Queue<T> &operator =(
		const Queue<T> &otherQueue);

	// Destructor
	~Queue();

	// Determine emptiness or fullness
	bool isEmpty() const;
	bool isFull() const;

	// See value at front
	T front() const;

	// Add value to rear
	inline void add(const T &val);

	// Remove value at front
	void del();

private:
	T *elements;    // Point to dynamic array that will store each person in line
	int capacity;   // Size of the line (group) in each sale
	int frontIndex; // will be for each person that is at the head of the line
	int numStored;  // Number values stored

};

template<class T>
Queue<T>::Queue(int size)
{
	elements = new T[size];  // allocate dynamic array
	capacity = size;
	frontIndex = 0;
	numStored = 0;
}

// Copy constructor
template<class T>
Queue<T>::Queue(const Queue<T> &otherQueue)
{
	// Copy non-dynamic array members.
	capacity = otherQueue.capacity;
	frontIndex = otherQueue.frontIndex;
	numStored = otherQueue.numStored;

	// Allocate new array for copy of other queue.
	elements = new T[capacity];

	// Copying *all* array elements--HOW ONLY COPY
	// THOSE OCCUPIED?
	for (int i = 0; i < capacity; i++)
		elements[i] = otherQueue.elements[i];
}

// Destructor
template<class T>
Queue<T>::~Queue()
{
	delete[] elements;  // Deallocate dynamic array
	elements = NULL;     // Avoid dangling pointer
	capacity = 0;        // Reset other members
	frontIndex = 0;
	numStored = 0;
}

// Assignment operator
template<class T>
Queue<T> &Queue<T>::operator =(
	const Queue<T> &otherQueue)
{
	// Avoid copying if assigning object to self.
	if (this != &otherQueue)
	{
		// Copy non-dynamic array members.
		capacity = otherQueue.capacity;
		frontIndex = otherQueue.frontIndex;
		numStored = otherQueue.numStored;

		// Deallocate old array.
		delete[] elements;

		// Allocate new array for copy of other queue.
		elements = new T[capacity];

		// Copying *all* array elements--HOW ONLY COPY
		// THOSE OCCUPIED?
		for (int i = 0; i < capacity; i++)
			elements[i] = otherQueue.elements[i];
	}

	// Return self.
	return *this;
}

// Accessors

template<class T>
bool Queue<T>::isEmpty() const
{
	return numStored == 0;
}

template<class T>
bool Queue<T>::isFull() const
{
	return numStored == capacity;
}

template<class T>
T Queue<T>::front() const
{
	if (numStored == 0)
	{
		cerr << "Queue empty: no element on front" << endl;
		return T();
	}

	// Return element at front.
	return elements[frontIndex];
}

// Mutators

// Add value to rear
template<class T>
void Queue<T>::add(const T &val)
{
	if (numStored == capacity)
	{
		cerr << "Queue full: cannot add element" << endl;
		return;
	}

	// ADD TO REAR (NO LONGER STORES INDEX OF REAR).
	int newRearIndex = (frontIndex + numStored) % capacity;
	elements[newRearIndex] = val;
	numStored++;
}

// Remove value at front
template<class T>
void Queue<T>::del()
{
	if (numStored == 0)
	{
		cerr << "Queue empty: cannot delete element" << endl;
		return;
	}

	// REMOVE ELEMENT THAT IS AT FRONT.
	frontIndex++;
	if (frontIndex >= capacity)  // wraparound
		frontIndex = 0;
	numStored--;
}
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
//first part of main
#include <iostream>
#include <iomanip>
#include <iterator>
#include <vector>
#include <algorithm> //allow for searching


#include "Queue.cpp"
#include "searchList.cpp"
#include "Sale.h"

template <class T> //CHANGE: to dynamic array
void seatChart(vector<vector<T>> seat, const int &row, const int &col)
{
	//CHANGE: create variable to output the row and seat(column)
	int i, j;

	// Display seat table legend
	cout << "o = Seats Available\n";
	cout << "x = Seats Unavailable\n";
	cout << "Seats:  1  2  3  4  5  6  7  8  9  10" << endl;

	// Loop to generate the rows
	for (i = 0; i < row; i++) {
		// Beginning of each row
		// Note: display of "row number" is added by 1, i++ increments i and stores the new value as i, i + 1 will add 1 to i and not store its new value, this adjustment is because the array begins at 0 and not 1
		cout << "Row" << setw(3) << (i + 1);
		// Content of each row
		for (j = 0; col > j; j++) {
			cout << setw(3) << seat[i][j];
		}
		// End of row
		cout << endl;
	}
}


bool validateOption(int option);
bool validateRow(const int &row); 
bool validateCol(const int &col);
void ticketPrice(int &rowselect, double &price);
bool validateTransaction(const int &num);

//const variables CHANGE: UPPERCASE
const int numRow = 10;
const int numCol = 10;
const char unavailable = 'x';
const char available = 'o';
const int lastMenuChoice = 4;
const int firstMenuChoice = 1;

//global variables
int transaction = 1;



using namespace std;

int main()
{

	//theatre being open
	bool open = true;

	int option;
	int rowselect;

	//sale record
	//is of type sale to access sale class
	SearchList<Sale> sold;

	//vector to hold transactions that were search up for returns
	vector<Sale> returnedSale;

	//initialize 2d vector for seating
	vector<vector<char>> seat(numRow, vector<char>(numCol));

	//set all seats to available
	for (int i = 0; i < numRow; i++)
	{
		for (int j = 0; j < numCol; j++)
		{
			seat[i][j] = available;
		}
	}


	while (open)
	{
		//display seating chart
		seatChart(seat, numRow, numCol);


		// Display Menu selections
		cout << "\nTicket Sales Menu:\n\n";
		cout << "1)  Purchase Ticket\n";
		cout << "2)  Returns Search\n";
		cout << "3)  List Transaction Report\n";
		cout << "4)  Exit\n\n";
		cout << "=========================\n";
		cout << "Enter Menu Choice: ";
		cin >> option;
		cout << endl << endl;

		bool valid;

		valid = validateOption(option);
		//validate option
		if (!valid)
		{
			cout << "Invalid entry please reenter your option" << endl;
		}
		else //continue if the option was valid
		{
			//cout << "before switch " << endl;
			switch (option)
			{
				//cout << "switch" << endl;
				//option 1 will change the available seats to unavailable. if chosen seat is unavailable it will display a resubmission
			case 1: {

				double totalticketsale = 0.00;

				//group size
				int size;

				//user requested row 
				int reqRow;

				//user requested col
				int reqCol;

				//display transaction number
				cout << "Transaction number: " << transaction << endl;

				//get group size to know how many in the line
				cout << "How many tickets will you need? ";
				cin >> size;

				cout << endl << endl;

				//initiale queue
				//sets size for queue
				int ticketNum = 1;
				Queue<int> custQueue(size);

				while (!custQueue.isFull() && ticketNum <= size)
				{
					custQueue.add(ticketNum);
					ticketNum++;
				}

				// go through the line getting price of each person in line
				while (!custQueue.isEmpty())
				{
					//price of seat
					double price = 0;

					//get and validate row and col
					cout << "Please select you seat for ticket #" << custQueue.front() << endl;
					cout << "please enter the row ";
					cin >> reqRow;

					cout << "Please enter the seat ";
					cin >> reqCol;

					cout << endl;

					valid = validateRow(reqRow);//= reqRow;
					//cout << "after validate row\n";

					//if invalid continue to ask till valid row
					while (!valid)//!validateRow(reqRow))
					{
						cout << "invalid row entry, please reenter valid row selection." << endl;
						cin >> reqRow;
						
						valid = validateRow(reqRow);
					}

					//validate selection
					valid = validateCol(reqCol);
					//cout << "after validate col\n";
					//if invalid continue to ask till valid seat(column)
					while (!valid)//!validateCol(reqCol))
					{
						cout << "invalid row entry, please reenter valid row selection." << endl;
						cin >> reqCol;
						validateCol(reqCol);
						valid = reqCol;
					}

					bool validSeat;

					//validSeat = seat[reqRow - 1][reqCol - 1];

					//buy tickets if it is available 'o'
					//user will enter based on 1 as the start
					//decrement the request to validate in vector 0 based
					if (seat[reqRow - 1][reqCol - 1] == 'o')
					{
						//set the seat as now unavailable
						seat[reqRow - 1][reqCol - 1] = 'x';

						//preceed to prcess payment of seat
						ticketPrice(reqRow, price);
						// Add a sold ticket price to the total sale amount (price is variable overwritten for each purchase, totalticketsale is global variable that has each price added to it)
						totalticketsale += price;
						cout << "Sold Ticket Price: $" << price << endl;
						cout << "Total sale: $" << totalticketsale << endl << endl;

						
					}// Not available - already sold (#)
					else
					{
						validSeat = false;
						while (!validSeat)
						{
							// Tell user that seat is already sold
							cout << "Sorry, This seat is already taken.";
							cout << "Please choose another seat." << endl;

							//get and validate row and col
							cout << "Please select you seat for ticket #" << custQueue.front() << endl;
							cout << "please enter the row ";
							cin >> reqRow;

							cout << "Please enter the seat ";
							cin >> reqCol;

							valid = validateRow(reqRow);//= reqRow;
							//cout << "after validate row\n";

							//if invalid continue to ask till valid row
							while (!valid)//!validateRow(reqRow))
							{
								cout << "invalid row entry, please reenter valid row selection." << endl;
								cin >> reqRow;

								valid = validateRow(reqRow);
							}

							//validate selection
							valid = validateCol(reqCol);
							//cout << "after validate col\n";
							//if invalid continue to ask till valid seat(column)
							while (!valid)//!validateCol(reqCol))
							{
								cout << "invalid row entry, please reenter valid row selection." << endl;
								cin >> reqCol;
								validateCol(reqCol);
								valid = reqCol;
							}

							if (seat[reqRow - 1][reqCol - 1] == 'x')
							{
								//set the seat as now unavailable
								seat[reqRow - 1][reqCol - 1] = 'o';

								//preceed to prcess payment of seat
								ticketPrice(rowselect, price);
								// Add a sold ticket price to the total sale amount (price is variable overwritten for each purchase, totalticketsale is global variable that has each price added to it)
								totalticketsale += price;

								cout << "Sold Ticket Price: $" << price << endl ;
								cout << "Total sale: $" << totalticketsale << endl << endl;



								
								validSeat = true;

							}

						}
					}

					//add this groups sale to the day
					//sold.addRear(size, transaction, totalticketsale);

					custQueue.del();
					
				}//end queue

				//add new sale
				Sale newSale;
				newSale.setTrans(size,transaction,totalticketsale);

				sold.add(newSale);

				 sold.display();

				//increment transaction number
				transaction++;
				//cout << "end queue " << endl;

				break;
			}//end case 1 
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//second part of main
case 2: {

				//transaction number
				int searchedTrans;

				//Transaction search
				cout << "Please enter the transaction number: ";
				cin >> searchedTrans;

				cout << endl;

				//validate search
				validateTransaction(searchedTrans);

				while (!validateTransaction(searchedTrans))
				{
					cout << "invalid transaction number.";

					cout << "Please enter the transaction number You want to look up: ";
					cin >> searchedTrans;
					 
					cout << endl;
					//validate search
					validateTransaction(searchedTrans);
				}

				//SearchList<Sale> sales;
				Sale singleSale;
				//findSale.addRear(0, searchedTrans, 0);

				singleSale.setTrans(0, searchedTrans, 0.0);

				bool found;

				found = sold.find(singleSale);

				if (!found)
					cout << "No transaction found for # \"" << searchedTrans << "\"" << endl;
				else
				{
					//CHANGE: to remove the sale from single sale
					cout << "Found transaction: " << searchedTrans << endl;
					singleSale.outPut();
					returnedSale.push_back(singleSale);
					//CHANGE: remove the transaction from the linked list to only hold sales that weren't returned
					cout << endl << endl;
				}

				break;
				//cout << "end case 2 " << endl;
			}//end case 2
			case 3: //listing of the sold tickets and the returned tickets
			{
				cout << "case 3" << endl;
			
				

				 //print out all the transactions in sold
				//while (!sold.isEmpty())
				//{
					sold.display();
				//}

				//print out all the returns 
				cout << "end case 3" << endl;
			}//end of case 3


			}//end of switch




		}//end of else


		
	}//end of while
		
	
	return 0;
	
}






//validate the entry of the option
bool validateOption(int option)
{
		//bool valid = false;

		//check if the digit is now within range
		if (option <= lastMenuChoice || option >= firstMenuChoice)
			return true;
			//valid = true;

	return false;
}
	
bool validateRow(const int &row)
{
	//bool valid = false;

	//check if entry is a digit
	
	
		//check if the range in the row is valid
		//user will enter 1 but row starts with 0 based
		if (row <= numRow || row > 0)
			return true;
			//valid = true;
	
	return false;
}


bool validateCol(const int &col)
{
	//bool valid = false;

	
		//check if the range in the row is valid
		//user will enter 1 but row starts with 0 based
		if (col <= numCol || col > 0)
			return true;
			//valid = true;
	

	return false;
}

//Prices for each row of the theater.
void ticketPrice(int &rowselect, double &price) {
	// Change price based on row...the closer the row, the more expensive
	switch (rowselect) {
	case 1: {
		price = 80.00;
		break;
	}

	case 2: {
		price = 75.00;
		break;
	}

	case 3: {
		price = 70.00;
		break;
	}

	case 4: {
		price = 65.00;
		break;
	}

	case 5: {
		price = 60.00;
		break;
	}

	case 6: {
		price = 55.00;
		break;
	}

	case 7: {
		price = 50.00;
		break;
	}

	case 8: {
		price = 45.00;
		break;
	}

	case 9: {
		price = 40.00;
		break;
	}

	case 10: {
		price = 35.00;
		break;
	}
	}

}

//validate searched transaction number
bool validateTransaction(const int &num)
{
	//validate if it is a digit
	bool valid = false;

		//check if the digit is now within range
		
		if (num <= transaction || num >= 1)
		{
			valid = true;
			return valid;
		}

		//if there is no transaction history 
		if (num <= 0)
		{
			return valid;
		}
	

	return valid;
}
Hello JayGln,

WOW. Thank you. I start looking into it.

Andy
Hello JayGln,

When I loaded up your program I had many errors to work out before I could test it.

I will start in "main".
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
#include <iostream>
#include <iomanip>
#include <iterator>
#include <vector>
#include <algorithm> //allow for searching

#include "Queue.h"
#include "searchList.h"
#include "Sale.h"

//const variables CHANGE: UPPERCASE
const int NUMROW = 10;
const int NUMCOL = 10;
const char UNAVAILABLE = 'x';
const char AVAILABLE = 'o';
const int LASTMENUCHOICE = 4;
const int FIRSTMENUCHOICE = 1;

template <class T> //CHANGE: to dynamic array
void seatChart(std::vector<std::vector<T>> seat)
{
	//CHANGE: create variable to output the row and seat(column)
	//int i, j; // <--- Best defined in for loop.

	// Display seat table legend
	std::cout << "o = Seats Available\n";
	std::cout << "x = Seats Unavailable\n\n";
	std::cout << "Seats:  1  2  3  4  5  6  7  8  9  10" << std::endl;

	// Loop to generate the rows
	for (int row = 0; row < NUMROW; row++)
	{
		// Beginning of each row
		// Note: display of "row number" is added by 1, row++ increments row and stores the new value as row, row + 1 will add 1 to row and not store its new value, this adjustment is because the array begins at 0 and not 1

		std::cout << "Row" << std::setw(3) << (row + 1);

		// Content of each row
		for (int col = 0; col < NUMCOL; col++)
		{
			std::cout << std::setw(3) << seat[row][col];
		}
		// End of row
		std::cout << std::endl;
	}
}

I moves the constant variables above the function to make better use of them. Also made the in capital letters as they should be.

The second and third parameters of the function are not needed. And passing them by reference does not help in any way as the global variable you are passing is defined as a constant and the function defines the variables as constants, which means they can not be changed and passing a simple variable by reference does not have any advantage unless you need to change its value.

By putting the constant variables above the function all you have to do is use them.

Defining "i" and "j" outside the for loop has no advantage here. It is better to define the variable in the for loop and keep the variable local to the for loop. About the only reason for defining the for loop variable outside the for loop is if you need it later after the for loop ends. Which is not needed here.

I changed "i" and "j" to "row" and "col" because it makes the code easier to read and follow.

The line using namespace std; should be moved above the function, but it is best not to use it in the first place.

After I qualified everything in the function I noticed the "using" statement and realized it should be moved, but since I changed the function I just left it alone.

I realize that defining int transaction = 1; as a global variable may appear to make things easier, but it is also easier for something to change its value when you least expect it to. Other than variables defined as a constant it is better to stay away from global variables.

in the while loop the line seatChart(seat, numRow, numCol); is a problem. Since seat chart is a template function you need to specify the type when calling the function. seatChart<char>(seat);. Notice since "numRow" and "numCol" are global constants you do not need to send them to the function.

When it comes to a menu I like to put the menu in a function where I can get the user's choice and then validate the entry and finish the function by returning a valid choice only. Your way works and I am not suggesting that you change it here, but something to keep in mind for the future. In the "menu" function most of the code stays in a do/while loop until you have a valid choice to return. If you are interested let me know and I will put something together for an example.

When I ran the program the "menu" has four choices, but the "switch" only has three cases. You need a "case 4:" to end the program.

So far I have only tested "case 1" and not as completely as it needs. For what I have tried it works.

In "Sales.h" I added the line friend std::ostream& operator <<(std::ostream& out, const Sale sales);.

And in "Sales.cpp" I added the function:
1
2
3
4
5
6
std::ostream& operator <<(std::ostream& out, const Sale sale)
{
	out << sale.getTransNum();

	return out;
}

This is because of what should be "searchList.h". Which reminds me that it is not a good practice to use "#include" to incluse ".cpp" files in a ".cpp" file. Since "searchList" starts as header, but needs the functions because of the template usage it should be a ".h" or ".hpp" file. I like the ".hpp" to go with the ".cpp" extension.

In the "searchList" file in the "private" section you define "struct Node" and inside that you define T info; where "T" ends up being the class "Sale". Later on in the function "SearchList<T>::display()" the line cout << traverseP->info;. "info" is defined as a class of type "Sale" and you are trying to print the whole class which does not work. That is why I did the overloaded insertion operator (<<) in the "Sale" class. You will need to decide what you want to display and change it accordingly. The change now is
std::cout << "Transaction Number: " << traverseP->info << '\n' << std::endl;. The "Transaction Number: " can just as easily be put in the function for the overloaded << operator.

The other change I made in the struct Node is Node<T> *nextP; to Node *nextP;. This does not need to be a templated variable. You have already set the type for "T" before the struct. And the pointer for "nextP" is to the "Node" not something else.

I do not think I have missed anything I have changed but I could have. There wer so many problems when I started.

Hope that helps,

Andy
Andy THANK YOU!

I'm at a loss with the use of the overloaded ostream operator. Does that only work when it is trying to print out anything specifically from the class that it is in, or whatever object/linked list I send to it? Could I do
1
2
3
4
5
6
std::ostream& operator <<(std::ostream& out, const Sale sale)
{
	out << sale.display();

	return out;
}


to use my function to display the whole object, so it includes all the data?
My professor told me to mimic his code that we did in class of a linked list that he output the whole object. One of the differences was that he didn't put his node struct inside private

1
2
3
4
5
6
7
// Node stores data in linked list.
template<class T>
struct Node
{
	T info;
	Node<T> *linkP;
};


1
2
3
4
5
6
7
8
9
10
template<class T>
void History<T>::output() const
{
	cout << "History:";

	for (Node<T> *traverseP = firstP;
			traverseP != NULL;
			traverseP = traverseP->linkP)//linkP is like my nextP
		cout << " " << traverseP->info;
}



The fourth case I was going to take out, I was only going to do the purchase of seats and tickets, searching a transaction to return, remove it from the list and putting that into a returns vector, the last 3rd case was to display all the sales that wasn't returned and the returned under that.
Any help that you can give is very appreciative. I have some other things that I have to change as well like changing the 2d vector to dynamic 2d array.
I will be putting this up and changing things using my Git
https://github.com/GlennJay/MovieTheatreSimulation
I went and put in the changes that you suggested and the using the overloaded << as well inside my public sale class. But now i'm getting a LNK 2019 error of all my functions inside my searchlist class. I really hate when I think I have a handle on something then come to find out i've been doing it wrong. Thank you for everything
Hello JayGln,

I was going to ask what IDE you are using, but when I followed the link to gibhub I found my answer.

You should never put using namespace std; in a header. It is bad enough to use it at all, hopefully in the next class you will learn not to use it, but in a header file it can cause even more problems. Give this a read http://www.lonecpluspluscoder.com/2012/09/22/i-dont-want-to-see-another-using-namespace-xxx-in-a-header-file-ever-again/ I think you are OK with the newer files, but I did see this in one of the older files.

Let us start with this example of yours:
1
2
3
4
5
6
7
// Node stores data in linked list.
template<class T>
struct Node
{
	T info;
	Node<T> *linkP;
};

or to look at it another way:
1
2
3
4
5
6
// Node stores data in linked list.
struct Node
{
	Sale info;
	NodeSale*linkP;
};

"info" is an object of class "Sale" to allow you access to its functions.
The other line is trying to create something I do not believe will work. "linkP" just needs to be a pointer of type "Node" so it knows where to go next in the linked list.

Now when you write std::cout << aVariable; where "aVariable" is a "bool", "char", "some type of int", "double" or "std::string" or even a C style char array string the "cout" knows how to deal with these types of variables.

When you do cout << " " << traverseP->info; "info" is an object of a class and the "cout" does not know what you want to send to the screen or how to format it. In this case you can either replace the "cout" with a function call to a class member function to do the printing to the screen or overload the insertion (<<) operator which sets up something that "cout" can understand. Something I thought of, but did not have a chance to try yet:
cout << " " << traverseP->info.getTransNum(); At least this would return something that "cout" can deal with.

The overloaded operator (<<) I showed you can be changed to print whatever you need. This could be done on one line or several. I believe that making any overloaded operator a friend of the class is the proper way. Just to see what would happen I tried:
1
2
3
4
5
6
7
8
9
10
11
12
// Equality operator so that products can be compared.
bool operator ==(const Sale &prod1,
	const Sale &prod2);
// Postcondition: Compare as equal if have same id.

// Less than operator so that products can be compared.
bool operator <(const Sale &prod1,
	const Sale &prod2);
// Postcondition: Compare as less than if id of first is
// less than id of second.

std::ostream& operator <<(std::ostream& out, const Sale sales);  // <--- Added. 

This worked, but all three should be made a "friend" of the class if I understand it correctly.

The other thing I noticed with your files. "Sale.h" and "Sale.cpp" if fine and done the way it should be keeping the code separate from the class definition. Files that cause a problem, as an example, "searchList.h" and "searchList.cpp". When you start the header file with:
1
2
3
4
5
6
7
template<class T>
class SearchList
{
	public:

		//constructor
SearchList();

It tends to work best when the functions immediately follow the class definition. This has to do with the use of template<class T>. I have found the trying to use two different files is always a problem.

When I set up version of the program I created a file "SearchList.h" and put the class definition along with the class function to make proper use if the template<class T>. The way you posted your code I took it to be one file as it should be. I can see how including the "SearchList.cpp" file in "main" brings together both "SearchList.h" and "SearchList.cpp" into one place, but this not the best way to do this.

You wrote:
I have some other things that I have to change as well like changing the 2d vector to dynamic 2d array.
Unless you have to use a dynamic array I would stay with the 2D vector.

The "LNK 2019 error" is not an easy error to understand, but as I have recently learned, and in simpler terms, it means that you are trying to call a function in one file and the function is defined in another file, but there is no connection between the two files and the compiler does not know about the function that is defined in another file. A lot of the time this is due to misspelled words not matching or the offending file could just be missing a header file.

I know I have done some differently than you have, but when I set up the overloaded (<<) it did not give me any problems. With out seeing the code where you made the changes and how you did it along with what file(s) the errors are occurring in it is challenging to know what to do to fix the problem.

First I would start by putting the functions of "SearchList.cpp" at the end of the "SearchList.h" file and the same for "Queue.cpp" file. Then in "main", I call the file "main" because it contains the "main" function, but it could be called anything, I would use:
1
2
3
#include "Sale.h"
#include "Queue.h"
#include "searchList.h" 

It has been said the the include file order should make no difference, but sometimes it does.

Another possibility is that putting templated class and functions in different files could be causing a problem.

I was thinking about taking the files from "github" and creating a new solution until I started thinking about some of the files like "SearchList.cpp". Is this file part of the project or just a file? If part of the project it is very likely that this file is compiled before "main". It could also be a reason for the "LNK 2019 error".

BTW I use VS2017 which should be the same or similar to what you are using.

If I have missed anything let me know.

Hope that helps,

Andy
Hello Andy,

Sorry I haven't responded I was trying to find a way to make everything work by the time I had to submit it tonight. I didn't want you to think I was ungrateful for all the help, time and energy you put into my project. I changed and took out all the namespace in the files except my main. I had to change the self created linked list to STL list with open chaining hash. I was finally able to get the ostream operator to print out the data I wanted. I wanted it to output the function but I had to just play with the << with some"\n" to be creative on my spacing. I am not fully done with this and thankfully he gave all of an extension till tomorrow by 11:59pm lol. I had to find a way to break out of one of my validation loops for the row/seat, that will just take a little time messing with the breakpoints and fixing my logic. I have updated the GIT with updated code as well if you ever want to look at it.
Thank you very much!!!!
Topic archived. No new replies allowed.