Alright, so I have spent days with with load, and just recently implemented check. I've read upon stuff, rewatched videos, all the good stuff.
I'm trying to do pset5 (misspellings) with Tries. I think I got the logic right, but something seems off. I got 2 problems (or probably more) that I can't seem to figure out:
1. When I run speller.c with the Austin Powers text, I get all words containing apostrophes as misspelled back and nothing else.
This means:
a) for some odd reason my code fails to identify apostrophes either in the load() of the check() function b) non-correct words are identified as correct (I'm guessing something might be wrong with bool is_word)
2. I realized I'm not sure about return in general. In my check() function I thought the function returns the (bool) value as soon as it hits a return statement - which should always happen in my last else if block. But it seems that is not the case. If I change the last return true to return false, then it lists all words, meaning everything was false.
This means:
a) All this time I was wrong about return, and it doesn't necessarily end a function b) something is really off with my code and for some reason it reaches the last return statement
Now... I'm not sure how much code I can show without breaching academic honesty, but I feel almost the whole thing is needed to identify the flaw(s). With that said, I'll try to post as little code as possible, if you guys think it's too much, I'll gladly remove it.
With that said, here's load():
bool load(const char* dictionary)
{
// creating root node and checking if it's NULL
root = malloc(sizeof(node));
node* current = root;
if (root == NULL)
{
printf("Could not create root node\n");
return false;
}
// setting root pointers to NULL
for (int i = 0; i < 27; i++)
{
root -> path[i] = NULL;
}
// opening dictionary for reading and checking if it is NULL
FILE* dic = fopen(dictionary, "r");
if (dic == NULL)
{
printf("Could not open dictionary\n");
return false;
}
// setting up variables for the iteration
//int count = 0;
int j = 0;
char buffer[LENGTH+1];
// iterate throught the dictionary, word by word
while (fgets(buffer, LENGTH + 1, dic) != NULL)
{
// resetting the current pointer at each word
current = root;
current -> is_word = false;
//iterate through each word, letter by letter
for (char* i = buffer; *i != '\n'; i++)
{
// creating a variable to store letters in
int templetter = i[j];
if (templetter >= 'a' && templetter <= 'z')
{
// checking if the node's path field is empty
if (current -> path[templetter - 'a'] == NULL)
{
node* newnode = malloc(sizeof(node));
if (newnode == NULL)
{
printf("Could not create new node\n");
return false;
}
// setting newnode's path field array to NULL, and is_word to false
newnode -> is_word = false;
for (int i = 0; i < 27; i++)
{
newnode -> path[i] = NULL;
}
// setting current pointer to point to newnode
current -> path[templetter - 'a'] = newnode;
}
else
{
// set the current pointer to the next node if it is already 'open'
current = current -> path[templetter - 'a'];
}
}
// same as above but for apostrophe
else if (templetter == '\'')
{
// checking if the node's path field is empty
if (current -> path[26] == NULL)
{
node* newnode = malloc(sizeof(node));
if (newnode == NULL)
{
printf("Could not create new node\n");
return false;
}
// setting newnode's path field array to NULL and is word to false
newnode -> is_word = false;
for (int i = 0; i < 27; i++)
{
newnode -> path[i] = NULL;
}
current -> path[26] = newnode;
}
else
{
current = current -> path[26];
}
}
else if (templetter == '\0')
{
current -> is_word = true;
}
j++;
}
j = 0;
}
return true;
}
I know, doing the same code twice is not the prettiest of solutions...
and here is check():
bool check(const char* word)
{
// declaring a variable to hold the current letter
int modletter;
// setting up a pointer for traversal
node* checker = root;
// iterating through each string in word
for (int z = 0; z < strlen(word); z++)
{
// if uppercase
if (word[z] >= 'A' && word[z] <= 'Z')
{
modletter = word[z] - 'A';
}
// if lowercase
else if (word[z] >= 'a' && word[z] <= 'z')
{
modletter = word[z] - 'a';
}
// if apostrophe
else if (word[z] == '\'')
{
modletter = 26;
}
// move pointer if path exists
if (checker -> path[modletter] != NULL)
{
checker -> path[modletter] = checker;
}
// check to see if at the current pointer there is a word ending
else if (checker -> path[modletter] == NULL)
{
if (checker -> is_word == true)
return true;
else
return false;
}
}
return true;
}
So... any hints from anyone? I've thought it through tons of times, and it seems correct to me. But obviously, it's not.