Code loops when you try to print the entire queue

Hello all,

I built a program around the concept of queues, while it compiles and allows input and removal of a member, printing ( selection e) causes the program to infinitely loop. I haven't been able to discover why.

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

#include <iostream>
#include <cstdlib>
#include <ctype.h>
#include <iomanip>

using namespace std;



class Queue{
	
	
struct node 
	{
		int info;
		struct node *next;
	};
		
	
	public:
		
		Queue();
		
		void enqueue();
		void dequeue();
		void theDisplay();
		void isVacant();
		void infoBack();
		void infoFront();
		void elementsTotal();
	
	private:
		
		node *back;
		node *front;
		int total;
		
	
};

Queue::Queue()
{
	back = NULL;
	front = NULL;
	total = 0;
}

void Queue:: infoFront()
{
	if (front == NULL)
	{
	cout << "No data at the front of  this queue, it is not populated" << endl ;
	}
	else 
	{
	   cout << front-> info << endl;
	}
}

void Queue:: infoBack()
{
	if (back == NULL)
	{
		cout << "No data at the  back of  this queue, it is not populated" << endl ;
	}
	else 
	{
	   cout << back-> info << endl;
	}
}

void Queue:: elementsTotal()
{
	if (total > 0)
	{
		cout << "There are " << total << "members in the queue " << endl;
	}
	else
	{
		cout << " there are no members in the queue" << endl;
	}
}

void Queue:: enqueue()
{
	int data;
	node *temp = new node;
	cout << "enter the info to equeue: " << endl;
	cin >> data;
	temp->info = data;
	temp->next = NULL;
	if(front == NULL && back == NULL)
	{
		front = back = temp;
	}
	back->next = temp;
	back = temp;
	total++;
}

void Queue:: dequeue()
{
	node *temp = new node;
	if(front == NULL)
	{
		cout << "The queue is not populated" << endl;
	}
	else
	{
		cout << "Info is" << front->info << endl;
		if(front == back)
		{
			front = back = NULL;
		}
		else
		{
			front = front->next;
		}
	}
	total --;
}

void Queue::isVacant()
{
	if (front == NULL)
	{
		cout << " The queue is not populated" << endl;
	}
	else
	{
		cout << " The queue is populated" << endl;
	}
}

void Queue::theDisplay()
{
	node *p = new node;
	p = front;
	if(front == NULL)
	{ 
		cout << "not info available" << endl;
	}
	else
	{
		while (p != NULL)
		{
			cout << endl << p->info;
			p = p->next;		
		}
	}	
}


int main()
{
	Queue queue;
	
	char select;
	
     while(true) 
	 
	 {
     	
     	cout << " ****************************"<< endl;
		cout << " ****************************" << endl;
		cout << "Please make your selection " << endl;
		cout << " A. Add to queue "<< endl;
		cout << " B. Remove from queue "<< endl;
		cout << " C. Print front of queue" << endl;
		cout << " D. Print back of queue" << endl;
		cout << " E. Print queue " << endl;
		cout << " F. Examine queue population "<< endl;
		cout << " G. Print number of queue members " << endl;
		cout << " X. Exit App " << endl;
		
		cin >> select;
		
		switch(toupper(select))
		{
			case 'A':
				queue.enqueue();
				break;
			case 'B':
				queue.dequeue();
				break;
			case 'C':
				queue.infoFront();
				break;
			case 'D':
				queue.infoBack();
				break;
			case 'E':
				queue.theDisplay();
				break;
			case 'F':
				queue.isVacant();
				break;
			case 'G':
				queue.elementsTotal();
				break;
			case 'X':
				queue.dequeue();
				break;
			default:
				cout << " invalid entry" << endl;
				break;
     	
	  }
		
}	
    return 0;
}

Last edited on
You have
1
2
int data;
cin >> data;

and
1
2
char select;
cin >> select;


If the stream has non-digits in it when it does the cin >> data;,
then (1) that input fails and (2) the stream (cin) goes into error state. All followup attempts to input will fail too, until that error state is cleared.

One should verify the success:
1
2
3
4
5
if ( cin >> data ) {
  // use data
} else {
  // handle error
}



However, how is the loop supposed to end?
Nothing does break out of the loop, does it?

Besides, why does 'X' dequeue()?


[EDIT]
1
2
3
void Queue:: dequeue()
{
	node *temp = new node;

Why a new, unused node there?
Where do you delete nodes?
Last edited on
@keskiverto,

so wrap the enqueue in an if/else statement with error handling?

the loop is just supposed to display all the elements, depending on if you decide to or not.

the X and dequeue is a ttpo its suppose to be exit(0).

deleting nodes in done in the dequeue function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Queue:: dequeue()
{
	node *temp = new node;
	if(front == NULL)
	{
		cout << "The queue is not populated" << endl;
	}
	else
	{
		cout << "Info is" << front->info << endl;
		if(front == back)
		{
			front = back = NULL;
		}
		else
		{
			front = front->next;
		}
	}
	total --;
}


ttpo

That would be clever if it wasn't itself a ttpo.

Anyway, why would you make a new node in the dequeue function? Surely you should be deleting a node!
So yes you are correct, the new node is useless. And it only seems to loop when one input is added. it does not with multiple.
There are various memory issues - removing a node doesn't free the memory and there's no class destructor to free the allocated memory. Note that this enqueues at the back and dequeues from the front. Perhaps:

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 <iostream>
#include <cctype>
#include <limits>

using std::cout;
using std::cin;

class Queue {
	struct Node {
		int info {};
		struct Node* next {};

		Node(int i) : info(i) {}
	};

public:
	Queue();
	~Queue();

	// To be provided if needed
	Queue(const Queue&) = delete;
	Queue& operator=(const Queue&) = delete;

	void enqueue();
	void dequeue();
	void theDisplay();
	void isVacant();
	void infoBack();
	void infoFront();
	void elementsTotal();

private:
	Node* back {};
	Node* front {};
	size_t total {};
};

Queue::Queue() {}

Queue::~Queue() {
	while (front) {
		const auto tmp {front};

		front = front->next;
		delete tmp;
	}
}

void Queue::infoFront() {
	if (total == 0)
		cout << "No data at the front of this queue - it is not populated\n";
	else
		cout << front->info << '\n';
}

void Queue::infoBack() {
	if (total == 0)
		cout << "No data at the back of this queue - it is not populated\n";
	else
		cout << back->info << '\n';
}

void Queue::elementsTotal() {
	if (total > 0)
		cout << "There are " << total << " members in the queue\n";
	else
		cout << "There are no members in the queue\n";
}

void Queue::enqueue() {
	int data {};

	while ((cout << "Enter the integer number to enqueue: ") && !(cin >> data)) {
		std::cout << "Not a number\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	auto temp {new Node(data)};

	if (front == nullptr)
		front = back = temp;
	else {
		back->next = temp;
		back = temp;
	}

	++total;
}

void Queue::dequeue() {
	if (total == 0)
		cout << "The queue is not populated\n";
	else {
		cout << "Info is " << front->info << '\n';

		const auto tmp {front};

		front = front->next;
		delete tmp;

		if (front == nullptr)
			back = nullptr;

		--total;
	}
}

void Queue::isVacant() {
	if (total == 0)
		cout << " The queue is not populated\n";
	else
		cout << " The queue is populated\n";
}

void Queue::theDisplay() {
	if (total == 0)
		cout << "No info available\n";
	else
		for (auto p = front; p != nullptr; p = p->next)
			cout << '\n' << p->info;

	cout << '\n';
}

int main()
{
	Queue queue;
	char select {};

	while (select != 'X') {
		cout << "\n ****************************\n";
		cout << " ****************************\n";
		cout << "Please make your selection\n";
		cout << " A. Add to queue\n";
		cout << " B. Remove from queue\n";
		cout << " C. Print front of queue\n";
		cout << " D. Print back of queue\n";
		cout << " E. Print queue\n";
		cout << " F. Examine queue population\n";
		cout << " G. Print number of queue members\n";
		cout << " X. Exit App\n\n";
		cout << "Option: ";

		cin >> select;
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
		select = static_cast<char>(std::toupper(static_cast<unsigned char>(select)));

		switch (select) {
			case 'A':
				queue.enqueue();
				break;

			case 'B':
				queue.dequeue();
				break;

			case 'C':
				queue.infoFront();
				break;

			case 'D':
				queue.infoBack();
				break;

			case 'E':
				queue.theDisplay();
				break;

			case 'F':
				queue.isVacant();
				break;

			case 'G':
				queue.elementsTotal();
				break;

			case 'X':
				//queue.dequeue();
				break;

			default:
				cout << "Invalid entry\n";
				break;
		}
	}
}

Last edited on
Thank you so much, I understand now.
Registered users can post here. Sign in or register to post.