Need assistance with never ending loop using ncurses and a doubly linked list

I have an assignment to use ncurses and a doubly linked list to create a single line text editor when run on the Linux server.
I'm sorry for the length and complexity, but I am not sure where my error is. Everything I have tried still results in the program printing either my input or the first line repeatedly.
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
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
#include <iostream>
#include <ncurses.h>
#include <unistd.h>
#include <cctype>
using namespace std;

struct Node {
	char data;
	Node* next;
	Node* prev;
};

class Line {
	private:
	Node* head;
	Node* tail;
	Node* cursor;

	public:
	// start with a Line that only contains a node of ' '  
	Line() {
		Node* start = new Node;				//start node
		head = start;					//head, tail, cursor are the same place
		tail = start;
		cursor = start;
		start->data = ' '; 				//making it empty
		start->prev = NULL;				//setting nulls on both ends
		start->next = NULL;	
	}
	
	// same as above, but load str into the list also
	Line(string str) {
		Node* first = new Node;				//making the first node
		head = first;					//head, tail, cursor are all at first
		tail = first;
		cursor = first;
		first->data = ' ';				//making first empty
		first->prev = NULL;				//setting nulls on both ends
		first->next = NULL;
		for(int i=0; i<= str.length(); i++) {		//using a for loop on the string
			if(i == 1 ) {
				cursor->prev = head;
				head->prev = NULL;
			}
			add(str[i]);				//add function to add new nodes
		}
		

	}

	// add the new node before the cursor
	void add(char key) {
		Node* findFront = cursor;			//node pointer to position head
		Node* findBack = cursor;			//node pointer to position tail
		Node* addMe = new Node;				//new node to add
		addMe->data = key;				//key is data in addMe node
		addMe->next = NULL;
		addMe->prev = NULL;

		if(!cursor->prev) {				//if the list is empty
			addMe->prev = NULL;			//the added node's prev is null
			addMe->next = cursor;			//addMe next is the cursor
			cursor->prev = addMe;			//cursor prev = addM
			head = addMe;

		}

		if(cursor->prev) {				//if the list is not empty
			cursor->prev->next = addMe;		//the node behind the cursor not points at addMe
			addMe->next = cursor;			//addMe next is now the cursor
			addMe->prev = cursor->prev;  		//addMe prev is the node that was behind the cursor
			cursor->prev = addMe;			//cursor prev is now addMe
		}	
	/*	//this is probably overkill
		while(findFront->prev != NULL) {				//while findFront exits
			findFront = findFront->prev;		//traverse to the beginning of list
		}
		head = findFront;				//head is the first node
		delete findFront;				//delete temp node pointer
		
		while(findBack) {				//while findBack exists
			findBack = findBack->next;		//traverse to end of list
		}
		tail = findBack;				//tail is end of the list
	*///	delete findBack;				//delete temp node pointer
	}


	// remove the node before the cursor
	void remove() {
		while(cursor->prev) {					//while there is something to delete
			Node* toDelete = cursor->prev;			//creating temp node to delete
			if (!cursor->prev->prev) {			//if you are deleting the only thing in the list
				cursor->prev = NULL;			// cursor prev is now null
				delete toDelete;			//deleting offending node
			}
			if (cursor->prev->prev) {			//if you are deleting a thing in the list
				cursor->prev->prev->next = cursor;	//the node behind the node behind cursor now points at cursor
				cursor->prev = cursor->prev->prev;	//cursor now points at the node two back from cursor
				delete toDelete;			//delete the offendind node
			}
		}
	}

	// print the line
	void print() {

		if(head == NULL) {				
			cout << "There is nothing here! This should never happen!" << endl;
		}	
		Node* temp = head;					//creating temp node for iteration set to head
		int counter = 0;					//counter so ncurses can highlight the cursor
		while(temp != NULL) {					//while the list exists
			if(temp == cursor) {				//if temp and cursor are the same
				attron(COLOR_PAIR(1));			//invert colors
				mvaddch(5,counter,temp->data);		//add color effect
//				cout << (*temp).data;
				attroff(COLOR_PAIR(1));			//return colors
			} else {
				cout << temp->data;			//otherwise cout data				
				temp = temp->next;			//iterate through
				counter++;				//increase counter
			}
		}
		
		// recall to print the cursor, that to turn use color
		// the code looks like this:
		//    attron(COLOR_PAIR(1));
		//    mvaddch(row, col, char);
		//    attroff(COLOR_PAIR(1));
	
	}

	// move the cursor left or right
	void moveCursor(char input) {
		if(input == 'l' && cursor->prev != NULL ) {		//if left arrow key is pressed and there is a node before the cursor
			cursor = cursor->prev;				//move the cursor
		}
		if(input == 'r' && cursor->next != NULL ) {		//if right arrow is pressed and there is a node after the cursor
			cursor = cursor->next;				//move the cursor
		}
	}

	// destructor deletes all nodes in the list
	~Line() {
		Node* check = head;					//temp nodes for distruction
		Node* destroy = head;

		while(!tail) {						//while not at the end
			check = check->next;				//iterate check
			delete destroy;					//destroy destroy
			destroy = check;				//set destroy to check
		}
		if(tail){						//at the end
			delete destroy;					//delete temp nodes
			delete check;
		}		
	}
};


int main() {
	// set up ncurses stuff
	initscr();
	keypad(stdscr, TRUE);	// lets the arrow keys work
	start_color();
	init_pair(1, COLOR_BLACK, COLOR_WHITE);
	noecho();				// makes the keystroke NOT be printed
	nodelay(stdscr, TRUE);	// makes getch NOT WAIT for input
	curs_set(0);			// turn off the regular cursor
	
	// declare line
	Line l("start with this text"); // construct the starting line
	int input = 'a';
	
	// modification loop
	while(input != 27) { // 27 is the escape key
		// get input
		input = getch();
		
		// put the input into the line or move the cursor
		if(isalpha(input) || input == ' ') {
			l.add(input);
		} else if(input == KEY_LEFT) {
			l.moveCursor('l');
		} else if(input == KEY_RIGHT) {
			l.moveCursor('r');
		} else if(input == KEY_BACKSPACE) { // backspace
			l.remove();
		}

		// display line with cursor and pause
		l.print();
		refresh();
		usleep(10000);
	}
	
	// exit
	endwin();
	return 0;
}
113
114
115
116
117
118
119
120
121
122
123
124
		while(temp != NULL) {					//while the list exists
			if(temp == cursor) {				//if temp and cursor are the same
				attron(COLOR_PAIR(1));			//invert colors
				mvaddch(5,counter,temp->data);		//add color effect
//				cout << (*temp).data;
				attroff(COLOR_PAIR(1));			//return colors
			} else {
				cout << temp->data;			//otherwise cout data				
				temp = temp->next;			//iterate through
				counter++;				//increase counter
			}
		}
note that you only change `temp' in the else part.
so, when `temp' reaches `cursor' it will remain there forever, hence your infinite loop

by the way, you should be using the i/o functions provided by ncurses
Registered users can post here. Sign in or register to post.