cfanatic, I think it's time for you to learn to use a debugger. You would have found the problem probably in less than 5 minutes yourself.
Here is one possible session. I'm using gdb here but you can choose any debugger you like, even with fancy GUI :-):
Code:
$ gdb -q ./test
Reading symbols from test...done.
(gdb) b spellcheck
Breakpoint 1 at 0x8048889: file test.c, line 91.
The first thing I do is setting a breakpoint as soon as your program enters the spellcheck function. You can also set breakpoints by line numbers but since you know that there's something wrong with this function the beginning of the function is a good starting point.
Code:
(gdb) r
Starting program: test
Breakpoint 1, spellcheck (word=0x804a060 "hello", dictionary=0x804b170)
at test.c:91
91 {
With "r" I start the program and it stops at the breakpoint (we're now at line 91). gdb also shows you the parameters for the function call.
Code:
(gdb) n
92 int x, ch, flag, cmpr, ctr = 0;
(gdb) n
96 while((ch = fgetc(dictionary)) != EOF)
(gdb) n
98 if((ch != '\n'))
(gdb) p ch
$1 = 104
With "n" you tell gdb to execute the next line. Thus you can step through the code line by line. (Notice: gdb will execute the current line and prints the next to be executed, i.e. if you see output like "98 if((ch != '\n'))" it means the program stopped at this line and hasn't executed it yet).
So we are at line 98 now and with "p ch" I can print the current value of ch (104 is the ASCII code for "h"). So I expect that the program enters the body of the if-statement. Let's see if that's right:
Code:
(gdb) n
100 word_in_dict[ctr] = ch;
(gdb) n
101 ctr++;
(gdb) n
102 continue;
(gdb) n
96 while((ch = fgetc(dictionary)) != EOF)
(gdb) p word_in_dict
$2 = "h\000\000\000\000\000\000\000^\210\004\b\b\260\004\b\364?-\000\000\000\000\000\000\000\000\000h\362\377\277\240F\022\000\005\000\000"
Until now the program works as expected. The first character was read and added to word_in_dict (you can see that "h" is the first element of the array, the rest is just garbage which happened to be already there at this memory location).
Code:
(gdb) watch ch == '\n'
Hardware watchpoint 2: ch == '\n'
(gdb) continue
Continuing.
Hardware watchpoint 2: ch == '\n'
Old value = 0
New value = 1
0x08048922 in spellcheck (word=0x804a060 "hello", dictionary=0x804b170)
at test.c:96
96 while((ch = fgetc(dictionary)) != EOF)
(gdb) p ch
$3 = 10
Now I could have continued to step through the code but this would be rather boring and time consuming. Instead I've chosen to set a watchpoint. This feature will set another kind of breakpoint which only stops the program if the given expression (here ch == '\n') is true. Thus I can jump directly to the next interesting part of the program: checking if we enter the else-branch if the read character is a newline. Just to show you that ch is really the newline-character (= ASCII code 10) I've printed it's value.
Code:
(gdb) n
98 if((ch != '\n'))
(gdb) n
106 word_in_dict[ctr] = '\0'; // add terminator to make string
(gdb) l
101 ctr++;
102 continue;
103 }
104 else
105 {
106 word_in_dict[ctr] = '\0'; // add terminator to make string
107
108 if((cmpr = strcmp(word, word_in_dict)) == 0) // compare word to dictionary word
109 {
110 return NULL; // match found, nothing further needs doing
Everything is still fine until now. We've entered the else-branch and are now on line 106 ("l" will print some lines before and after the current line, so it gives you a nice overview when you aren't sure where exactly you are in your program). Let's continue stepping through the code:
Code:
(gdb) n
108 if((cmpr = strcmp(word, word_in_dict)) == 0) // compare word to dictionary word
(gdb) p word_in_dict
$4 = "how\000\000\000\000\000^\210\004\b\b\260\004\b\364?-\000\000\000\000\000\000\000\000\000h\362\377\277\240F\022\000\005\000\000"
(gdb) p word
$5 = 0x804a060 "hello"
The next line to execute is the comparison. I print both word_in_dict and word to check if the have the expected values.
Code:
(gdb) n
112 ctr = 0; // reset array position to accept new word
(gdb) n
114 return word; // if no matches between word and any dictionary words, return word to main()
The words didn't compare equal as expected and ctr is set to 0. But look carefully now at our current line. We are at line 114 which means the next command will be the return statement. That's not what we want, so we've found our bug.
Just to prove that we will really return to main() after only comparing the first in the dictionary, I continued stepping through the code:
Code:
(gdb) n
116 }
(gdb) n
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
0x08048699 in main () at test.c:33
33 if(spellcheck(word, dictionary) == NULL)
It's true, we're back in main because the return statement is on the wrong location.
As I've said before, if you know some basic debugging commands (setting breakpoints, stepping through the code, printing variable values) you will be able to fix your bugs much faster than waiting for someone here on the forum.
Bye, Andreas