help with a bug in a link list

So I have created this link list for a class project. It seem to take all the data ok. The problem arises when the data is printed. if you run the code you will see the output ends up being junk. I need help in finding out why the output is not the words in the link list Sorry for all the code but you may want it all to see where I have gone wrong.

main.cpp
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
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string.h>
#include "menu.h"
#include "word.h"

using namespace std;

#define Word_OK (0)
#define Word_Not_Found (-1)
#define Word_already_Exist (-2)
#define Word_too_big (-3)
#define Dictionary_empty (-4)
#define File_error (-5)
#define Memory_error (-6)
#define Word_Unknown_Error (-20)
#define Buffer (200)
#define Max_len (30)
#define FILE_NAME "dictionary.txt"

/* Search the word in the list and print it if found. 
   return an error code if not found or the dictionary is empty. */
int SearchWord();
/* Add a word in the list from user input.
   return an error code if the word already exist or if input is too long. */
int InsertWord(Word *list);
/* Function used by InsertWord() and InitDictionary() to insert a new word in 
   the list at right position (order alphabetically by english word).
   return an error code if there is a memory allocation problem. */
int chainWord(char *en, char *fi, Word *list);
/* Remove a word from the list.
   return an error code if word not found. */
int DeleteWord();
/* Show all the words in the dictionary. This was first a debug function; but
   since it works, I kept it. Considere that as an extra feature.
   return an error code if the dictionnary is empty. */
int ShowAllWord(Word *list);
/* Print error if something goes wrong. */
void PrintError(int aErrorCode);
/* Read the saved words from the file and load it to the dictionary.
   return an error code if it don't manage to open the file. */
int InitDictionary(Word *list);
/* Save the words in the file and clean the memory before leaving the program.
   return an error code if there is a problem with the file. */
int ExitDictionary();
int putDictionary();
void insertAfter(char *en, char *fi, Word *nodeB);


//the first word of the dictionary that is shared with all functions in main
//Word *w;
//Word *node;



int main()
{
    Menu m;
    m.PrintHeader();
    m.PrintMenu();
	Word *list;
	list = new Word();
   // PrintError(InitDictionary(list));
    int errorcode = 0;
    char c;
    cout << "Choose option: ";
    cin >> c;
    fflush(stdin); //I want one option at the time, so flush the end of line
    while(c != 'e' && c != 'E'){
        switch(c){
            case 's':
            case 'S':
                 errorcode = SearchWord();
                 break;
            case 'i':
            case 'I':
                 errorcode = InsertWord(list);
                 break;
            case 'd':
            case 'D':
                 errorcode = DeleteWord();
                 break;
            case 'a':
            case 'A':
               errorcode = ShowAllWord(list);
                 break;
            default:
                 system("cls");
                 m.PrintMenu();
        }
        PrintError(errorcode);
        cout << "Choose option: ";
        cin >> c;
        fflush(stdin);
    }
    PrintError(ExitDictionary());
    system("PAUSE");
    return 0;
}

int SearchWord(){
  
    return Word_Not_Found;
	
}


int InsertWord(Word *list){
    cout << "Insert" << endl << "Enter English Word: ";
    char inE[Buffer] = {'a'};
    cin.getline(inE, Buffer);
    if(strlen(inE) > Max_len)
        return Word_too_big;
    cout << "Enter Finnish Word: ";
    char inF[Buffer] = {'a'};
    cin.getline(inF, Buffer);
    if(strlen(inF) > Max_len)
        return Word_too_big;
	
    int res = chainWord(inE, inF, list);
    if(res == Word_OK)
        cout << "Word insert OK" << endl;
		//putDictionary();
    return res;
}




int chainWord(char *en, char *fi, Word *list)
{
    //if the dictionary is empty we just need to set the first word
	cout << "inE = " << en << " inF = " << fi << endl;
	
    if(list->GetNext() == NULL)
	{
        Word *newNode;
		if(list->GetFront() == NULL)
		{
			newNode = new Word();
			list->SetFront(newNode);
			list->SetBack(newNode) ;
			newNode->SetPrev(NULL);
			newNode->SetNext(NULL);
			newNode->InsertEnglish("hello");
			cout << en;
			newNode->InsertFinnish(fi);
			cout << "" << endl;
		}
		
	}
	else
	{
		insertAfter(en, fi, list->GetBack());
	}
		
	return Word_OK;
}

//insert a node after  nodeB
void insertAfter(char *en, char *fi, Word *nodeB)
{
	Word *newNode;
	newNode=new Word();
	newNode->SetNext(nodeB->GetNext());
	newNode->SetPrev(nodeB);

	if(nodeB->GetNext()==NULL)
	{
		
		nodeB->SetBack(newNode); 
	}
	nodeB->SetNext(newNode);
	
}

int ShowAllWord(Word *list)
{
	Word* printNode;
	printNode= list->GetFront();
	
	
	while(printNode!=NULL)
	{
		
		cout << " \nEnglish: " << printNode->GetEnglish();
		cout << " \nFinnish: " << printNode->GetFinnish();
		printNode=printNode->GetNext();
	}
	cout<<endl;
	
	return 10;
}// print the Double Linked List from front

int DeleteWord()
{
	cout << "deleting word" << endl;
	return 10;
}
void PrintError(int aErrorCode){
     switch(aErrorCode){
         case Word_OK:
            break;
         case Word_Not_Found:
            cout << "Word not found!" << endl;
            break;
         case Word_already_Exist:
            cout << "The word already exist!" << endl;
            break;
         case Word_too_big:
            cout << "The word is too big!" << endl;
            break;
         case Dictionary_empty:
            cout << "Dictionary is empty!" << endl;
            break;
         case File_error:
            cout << "Error with file!" << endl;
            break;
         case Memory_error:
            cout << "Memory allocation problem!" << endl;
            break;
         case Word_Unknown_Error:
         default:
            cout << "Oppps Unknown Error!" << endl;
            break;
     }                       
}     

int InitDictionary(Word *list){
    ifstream dicoFile (FILE_NAME);
    if(!dicoFile.is_open())
        return File_error;
    char in[Buffer] = {'a'};
    char inF[Buffer] = {'a'};
    int line = 0;
    while(!dicoFile.eof()){
        if(line == 0){
            //first line must be English word
            dicoFile.getline(in, Buffer);
            line++;
        }else if(line == 1){
            //second line must be Finnish word
            dicoFile.getline(inF, Buffer);
            line++;
        }else{
            //third line is empty line to separate words; so we should have Finnish and English words
            if(strlen(in) == 0 || strlen(in) > Max_len || strlen(inF) == 0 || strlen(inF) > Max_len){
                cout << "There is a word in file that is not valid";
            }else{
                PrintError(chainWord(in, inF, list));
            }
            dicoFile.getline(in, Buffer);//read the line to make the loop going forward
            line = 0;//reset the line counter (next line is an English word or the end of the file)
        }
    }
    cout << "Words from file added to dictionary successfuly!" << endl;
    return Word_OK;
}

int ExitDictionary(){
    int errorcode = 0;

    system("cls");
    return errorcode;
}



menu.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include "menu.h"

using namespace std;
/* Implementation of the menu class. */
void Menu::PrintHeader(){
     cout << "*************************************" << endl
          << "****      Dictionary             ****" << endl
          << "****      By Your Name and ID    ****" << endl;
}

void Menu::PrintMenu(){
     cout << "*************************************" << endl
          << "***             MENU              ***" << endl
          << "*************************************" << endl
          << "S - Search"         << endl
          << "I - Insert"         << endl
          << "D - Delete"         << endl
          << "A - Show all words" << endl
          << "E - Exit"           << endl
          << "  - Any other key to clear the screen" << endl
          << "*************************************" << endl;
} 


Here is the rest of the code
menu.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef _MENU_H_
#define _MENU_H_

//this class was created as an exercise and also to reduce the size of code of
//the main.
class Menu{
    public:
       /*print the information about the program and the author.*/
       void PrintHeader();
       /*print the options for the user.*/
       void PrintMenu();
};

#endif



Word.cpp
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
#include <cstring>
#include <ctype.h>
#include <iostream>
#include "word.h"

/* Implementation of the word class. */

#define Word_OK (0)
#define Word_too_big (-3)
#define Buffer (200)
#define Max_len (30)

Word::Word(){
    pEnglish = NULL;
    pFinnish = NULL;
    next = NULL;
	front = NULL;
	back = NULL;
}

Word::~Word(){

}

int Word::InsertFinnish(char *aWord)
{
	pFinnish = aWord;
    return Word_OK;
}

int Word::InsertEnglish(char *aWord)
{
	pEnglish = aWord;
    return Word_OK;
}

 char *Word::GetEnglish()
{	
	return pEnglish;
}

 char *Word::GetFinnish()
{	
	return pFinnish;
}

Word *Word::GetNext()
{
	return next;
}
int Word::SetNext(Word *word)
{
	next = word;
	return 1;
}

Word *Word::GetPrev()
{
	return previous;
}
int Word::SetPrev(Word *word)
{
	previous = word;
	return 1;
}

Word *Word::GetFront()
{
	return front;
}
void Word::SetFront(Word *word)
{
	front = word;
}
Word *Word::GetBack()
{
	return back;
}
void Word::SetBack(Word *word)
{
	back = word;
}


Word.cpp
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
#ifndef _WORD_H_
#define _WORD_H_

class Word{
    public:
        /*Constructor*/
        Word();
        /*Destructor*/
        ~Word();
        /*add or replace the English word*/
        int InsertEnglish(char *aWord);
        /*add or replace the Finnish word*/
        int InsertFinnish(char *aWord);
        /*define the next word (the dictionnary will be a linked list of words)*/
        int SetNext(Word *aWord);
		/*define the previous word (the dictionnary will be a linked list of words)*/
        int SetPrev(Word *aWord);
		void SetFront(Word *word);
		void SetBack(Word *word);
        /*get the English word*/
        char *GetEnglish();
        /*get the Finnish word*/
        char *GetFinnish();
        /*get the next word in the dictionary*/
        Word * GetNext();
		 /*get the next word in the dictionary*/
        Word * GetPrev();
		Word * GetFront();
		 Word * GetBack();
        /*compare a word (used to search and sort in the dictionary)*/
        int Compare(const char *aWord);  
    private:
        char *pEnglish;
        char *pFinnish;
        Word *next;
		Word *previous;
		Word *front;       //pointer to front of list   
		Word *back;        //pointer to back of list 
};

#endif


Any help would be great.

thanks
Jason
Your english word "Hello" is a temporary string literal, which means when it goes out of scope, the pointer you have assigned to that address now points to garbage. The same thing for your Finnish word, you are assigning the pointer to the local variable char inF[Buffer] in InsertWord. Once that function is out of scope you will have garage at that address.
ok I fugured as much, but was not sure where the out of scope problem really was. the "hello" was just a test case.
So I put a
char *en *fi;
en = NULL;
fi = NULL;

in main and then changed the function prototype to

int InsertWord(Word *list, char *inE, char *inF);

it compiles fine but now it stops after I enter the English word.

This is what I came up with to fix the lose of scope. A hint in the right direction would be cool.

Thanks
Put break points in your code and look at the value of the variables in question.
Thanks for the suggestion. I have already done that. I have about 15 and thats how I new I had a scope problem, I just could not see where it was leave the scope.
My last post did not work. If I run it with
en[200]
fi[200]
in main and pass them to the function
int InsertWord(Word *list, char *inE, char *inF);

then it seems to work but I am not sure it is still doing the right thing as there is an error code being printed as if something is wrong.
I appreciate you help and responses.
Which error code? Since you have break points, you should be able to tell me exactly where the problem is occurring can you give a line number?

Scope:
1
2
3
4
5
6
7
int main()
{
    en[200];
    //....
    return 0;
}//Leaving main, en no longer in scope (that's why it works for you now)


1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
     char * pCh = NULL;
    {
         //...
         en[200];
         pCh = en;
         //....
     } //End of scope for en, however, pCh still lives... leads to problem

    return 0;
}


1
2
3
4
5
6
7
8
9
void myFunction(char * pCh)
{
    en[200];
    //....
    pCh = en;
    //....
    return;
}//en leaves scope no longer exists when this function returns, pCh now points to garbage


That is what is going on in your code.
Last edited on
Topic archived. No new replies allowed.