Doubly-Linked List and Referencing Errors

Hello,

Full disclosure, this is an assignment. I just need help figuring out how to fix my errors. And I apologize for the relatively messy code and badly-named variables (these will be fixed). I have spent many hours staring at it this week and I just can't seem to figure it out. We had to convert a single-line text editor which uses arrays to one that uses OOP and double-linked lists and I have been doing it in steps. I have, for the sake of convenience, put my headers, implementation and main all in one file.

I'm compiling this program in Hercules (the getch function uses C code).

I keep getting the error from the compiler saying "Undefined Symbol" for functions:
insertNode(char, Node);
deleteNode(Node*);
insertHead(char);

The full message is: ld: fatal: Symbol Referencing Errors. No output written to a.out collect2: ld returned with 1 exit status.

Help anyone?

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
// A fake single line text editor program.
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <termios.h>
//#include "main.h"

typedef char Letter;
using namespace std;


/****************************************************************************/


struct Node
{
	Letter m_letter;
	Node *next;
	Node *prev;
	friend class dblyLinked;
};

class dblyLinked
{
public:
	dblyLinked();
	int insertHead(Letter);
	bool isFull();
	bool isEmpty();
	int moveRight();
	int moveLeft();
	int insertSorted(Letter, Node*);
	int resetP();
	int deleteNode(Node*);
	void printList();
	int setP(Node*);
private:
	Node *head;
	Node *tail;
	Node *p;
	int length;
};

/****************************************************************************/



Letter getch();
int editor();

int main()
{
	return editor();
}


/**************************************************************************/



int editor()
{

	int insertHead(Letter);
	bool isFull();
	bool isEmpty();
	int moveRight();
	int moveLeft();
	int insertSorted(Letter, Node);
	int resetP();
	int deleteNode(Node*);
	void printList();
	int setP(Node*);


	Letter c;
	int i;				// KEEP
	int cursorPosition = 1;		// KEEP
	int length = 0;

	Node *tempPtr;
	try
	{
		tempPtr = new Node;
	}
	catch (bad_alloc)
	{
		std::cerr << "Bad Memory Allocation!";
		delete tempPtr;
	}

	Node *head = new Node;
	Node *tail = new Node;
	Node *currPtr = new Node;
	Node *p = head;

	system("clear");

	cout << " " << endl;
	cout << "^" << endl;

	while (1)
	{
		c = getch();
		// The Backspace key was pressed.
		if (c == 8)
		{
			if (length > 0)
			{
				Node *tempPtr = currPtr;
				deleteNode(tempPtr->prev);
				length--;
				cursorPosition--;
			}
		}
		// One of the cursor control keys was pressed.
		else if (c == 27)
		{
			c = getch();
			c = getch();

			if (c >= 49 && c <= 54)
			{
				// The Home key was pressed.
			if (c == 49)
				{
					p = head;
					cursorPosition = 1;
				}
				// The Delete key was pressed.
				else if (c == 51)
				{
					
					Node *tempPtr = currPtr;
					deleteNode(tempPtr);
					length--;
				}
				// The End key was pressed.
				else if (c == 52)
				{
					p = tail;
					cursorPosition = length+1;
				}
			// This gets rid of a character in the input stream
				c = getch();
			}
			// The Move Cursor Right key was pressed.
			else if (c == 67)
			{
				int moveRight();
				cursorPosition++;
			}
			// The Move Cursor Left key was pressed.
			else if (c == 68)
			{
				int moveLeft();
				cursorPosition--;
			}
		}

		else if (c > 31 && c < 127)	// WHERE STUFF GETS INSERTED!
		{
			currPtr->m_letter = c;
			if (p == head)
				insertHead(c);

			else
				insertSorted(c, *currPtr);

				length++;
				cursorPosition++;
		}

		system("clear");


		void printList();

		// Print text [] to the screen.
		i = 1;	

cout << endl;

		if (c == '.' || c == '?' || c == '!')	// node->c ==.....
		{
			break;
		}
		// Position the cursor.
		i = 1;
		while (i < cursorPosition)
		{
			i++;
			cout << " ";
		}
		cout << "^" << endl;
	}
	

	return 0;
}


Last edited on
The problem is those forward declarations.
Line 50: Letter getch();
Line 65: int insertHead(Letter);
... and so on.

That style of coding was common pre-ANSI C, which is pre prototypes, which is pre 1990. Please don't do it, even in C.
I'm confused; are you saying that I should not use forward declarations?

Anyway, another problem was the syntax of the function calls. insertSorted(c, *currPtr)SHOULD have been insertSorted(char c, Node *currPtr) and so on. Ah well. I couldn't find a segmentation fault in time for the deadline, but I sure know what I need to work on! Thanks for your help either way kbw. :)
Last edited on
.. are you saying that I should not use forward declarations?

Yes. You should be using prototypes.

Look at it this way. Some creates a library with functions that do something. They provide declarations (data types and function prototypes) in header files, and a library to link against.

The correct way to use such a library is to include the given header files to get declarations, and link against the libraries to get the code.

An incorrect way to uise such a library is to guess what a function might look like, create your own definition of that function, and use it.

That's what you've done with getch. It's an curses function, so you should pull in the relevant header file #include <curses.h> , and link against libcurses; or whatever your system provides.
Topic archived. No new replies allowed.