When I ran my code through the compiler, it displays all the misspelled word correctly as per the staff solution. However, the program does not end after displaying all the misspelled words and it also fails to show all of the benchmarks (WORDS MISSPELLED, WORDS IN DICTIONARY, TIME IN TOTAL,etc.). I am not sure where is it that I have went wrong in my code. My code from dictionary.c is as follows:
/**
* Implements a dictionary's functionality.
*/
#include <stdbool.h>
#include "dictionary.h"
//Declaration of data structure node
typedef struct node
{
char word[LENGTH + 1];
struct node* next;
}
node;
//Declaration of node pointer to hashtable
node* hashTable[HASHTABLESIZE];
//Tracking number of words in dictionary
int wordCount = 0;
//Variable to track loading and unloading of dictionary
bool loaded = false;
//declaration of hash function; credits: https://www.reddit.com/r/cs50/comments/1x6vc8/pset6_trie_vs_hashtable/
int hashValue(const char* word)
{
unsigned int hash = 0;
for(int i = 0, n = strlen(word); i < n; i++)
{
hash = (hash << 2) ^ word[i];
}
return hash % HASHTABLESIZE;
}
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
//word is const char* so read-only
//have to create array to store copy of contents of word
char wordBuffer[strlen(word)+1];
//ensure that the whole word is in lowercase
for(int k =0, n = strlen(word); k < n; k++)
{
wordBuffer[k] = tolower(word[k]);
}
//null-terminate the wordCopy array
wordBuffer[strlen(word)] = '\0';
//getting the index of hash table(bucket) with word
int index = hashValue(wordBuffer);
//cursor point to first node of linked list in that bucket
node* cursor = hashTable[index];
//find for word in the linked list
while(cursor != NULL)
{
//compare both strings
if(strcmp(cursor->word, wordBuffer) == 0)
{
return true;
}
//keep traversing list to find the word
//at last node where next field is NULL, cursor will also become NULL
cursor = cursor->next;
}
return false;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char *dictionary)
{
//opening dictionary file to read
FILE* file = fopen(dictionary, "r");
//checking dictionary file for NULL
if(file == NULL)
{
fprintf(stderr, "Could not open %s.\n", dictionary);
return false;
}
//ensuring indexes of hash table are empty
for(int i =0; i < HASHTABLESIZE; i++)
{
hashTable[i] = NULL;
}
//scanning dictionary file word by word
while(true)
{
//creation of a new node
node* newNode = malloc(sizeof(node));
//checking node pointer for NULL
if(newNode == NULL)
{
return false;
}
//read a word from dictionary and directly store in newNode->word
//don't need to use strcpy
fscanf(file, "%s", newNode->word);
//setting fields of node to NULL first
newNode->next = NULL;
//if end of file, free newNode
if(feof(file)){
free(newNode);
break;
}
//increase word count
wordCount++;
//generation of index of hash table into which node is to be chained to (hash function)
int index = hashValue(newNode->word);
//cursor pointing to the node
node* cursor = hashTable[index];
//ensure index of hash table is empty
if(cursor == NULL)
{
hashTable[index] = newNode;
}
//if index of hash table already has node attached to it
else
{
newNode->next = hashTable[index];
hashTable[index] = newNode;
}
}
fclose(file);
loaded = true;
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
//When dictionary is loaded, return the count of words in dictionary
if(loaded)
{
return wordCount;
}
//If not, execute exit code
else
{
return 0;
}
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
//Entering each bucket of hash table
for(int j = 0; j < HASHTABLESIZE; j++)
{
node* cursor = hashTable[j];
while(hashTable[j] != NULL)
{
//Freeing linked lists
while(cursor != NULL)
{
node* temp = cursor;
cursor = cursor->next;
free(temp);
}
}
}
loaded = false;
return true;
}
My dictionary.h file is as follows:
/**
* Declares a dictionary's functionality.
*/
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
// maximum length for a word
// (e.g., pneumonoultramicroscopicsilicovolcanoconiosis)
#define LENGTH 45
//number of buckets in hashtable
#define HASHTABLESIZE 65536
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char *word);
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char *dictionary);
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void);
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void);
#endif // DICTIONARY_H