So, I have struggled with this set for a long time and managed to answer many questions myself, but this one I don't even know where to look.
The only test I fail is the max length, so I thought maybe I wasn't allowing enough characters but the check returned is this:
If I understand correctly my program has both said the word is misspelled AND that it is in the dictionary. I'm not sure where to look for the error. I have run my program and it counts an extra word in the text for the text with the max length word. It does not do this on other short texts I have tried. Any help appreciated.
I haven't changed dictionary.h, so here's the code for dictionary.c:
/**
* Implements a dictionary's functionality.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cs50.h>
#include <ctype.h>
#include "dictionary.h"
const int CHARACTERS = 27;
unsigned int wordcount = 0;
//new structure node: contains bool to determine if is end of word and pointer to array
typedef struct node
{
bool word_complete;
struct node* child[CHARACTERS];
}
node;
//create root node
struct node* root = NULL;
struct node* newNode()
{
//allocate new node memory and automatically assign end of word a value of false
struct node* next = NULL;
next = (struct node*)calloc(1, sizeof(struct node));
next->word_complete = false;
//set pointer to first empty place in array
for (int i = 0; i < CHARACTERS; i++)
{
next->child[i] = NULL;
}
return next;
}
void insert(const char* string)
{
//start at root
struct node* current = root;
while (*string != '\n')
{
//create new node if no path
if (current->child[*string - 'a'] == NULL)
{
current->child[*string - 'a'] = newNode();
}
//next node
current = current->child[*string - 'a'];
//next character
string++;
}
//mark end of word
current->word_complete = true;
wordcount++;
}
bool search(struct node* root, char* string)
{
//false if Trie empty
if (root == NULL)
{
return false;
}
//set current node to root
struct node* current = root;
while(*string)
{
//go to next node
current = current->child[*string - 'a'];
//if string not in Trie (reached a NULL value)
if (current == NULL)
{
return false;
}
//go to next character
string++;
}
//if reach end of string: is word
return current->word_complete;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char *dictionary)
{
root = (struct node*)calloc(1, sizeof(struct node));
//check memory??
if (root == NULL)
{
fprintf(stderr, "Insufficient memory.\n");
return 1;
}
char str[LENGTH];
// open file
FILE *fp = fopen(dictionary, "r");
if (fp == NULL)
{
fprintf(stderr, "Could not open %s.\n", dictionary);
return 2;
}
while(fgets (str, 27, fp) != NULL)
{
int newline = strcspn(str, "\n");
for (int ch = 0; ch < strlen(&str[newline]); ch++)
{
insert(&str[ch]);
}
}
fclose(fp);
return true;
}
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char *word)
{
//change to lowercase:
char lower[LENGTH];
int size = strlen(word);
strncpy(lower, word, size);
lower[size] = '\0';
int i = 0;
while (lower[i] != '\0' )
{
lower[i] = tolower(lower[i]);
i++;
}
//search dictionary for word
return (search(root, lower));
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
return wordcount;
}
void erase(node *current)
{
for (int i = 0; i < CHARACTERS; i++)
{
if (current->child[i] != NULL)
{
erase(current->child[i]);
}
}
free(current);
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
erase(root);
return true;
}
**EDIT: Have printed the output of my loaded dictionary to the terminal in a file and all that was there for the max word was s. (final character). All other words were loaded correctly. I added + 1 to all LENGTH in code and then in output I got an empty line, the s was gone. I have tried debug50 and the problem is that for that one word it is not loaded to dictionary the problem code that is skipped over on this word is:
while(fgets (str, 27, fp) != NULL)
{
int newline = strcspn(str, "\n");
for (int ch = 0; ch < strlen(&str[newline]); ch++)
{
insert(&str[ch]);
}
}