I am having problems with Pset 5 Speller. I believe, I'm nearly there, I can get all functions to run and compile successfully, however my outputs are not quite right. I have attached comments to make it as easy to follow as possible. Any ideas what the issue might be? I'm thinking the load function might be the problem as word in dictionary returns: 0
Here is my Check50 response:
:) dictionary.c, dictionary.h, and Makefile exist
:) speller compiles
:( handles most basic words properly
expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( handles min length (1-char) words
expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( handles max length (45-char) words
expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( handles words with apostrophes properly
expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( spell-checking is case-insensitive
expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( handles substrings properly
expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:| program is free of memory errors
can't check until a frown turns upside down
Here is my Output
WORDS MISSPELLED: 17756
WORDS IN DICTIONARY: 0
WORDS IN TEXT: 17756
TIME IN load: 0.00
TIME IN check: 0.01
TIME IN size: 0.00
TIME IN unload: 0.00
TIME IN TOTAL: 0.01
Here is my code:
// Implements a dictionary's functionality
#include <stdbool.h>
#include "dictionary.h"
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table = no of hashcodes
const unsigned int HTSize = 10;
// Hash table
node *hashtable[HTSize];
//Global Variables Defined
int word_count;
FILE* input = NULL;
// Hashes word to a number HASH FUNCTION
unsigned int hash(const char *word)
{
unsigned int hash_value = 0;
for (int i = 0, length = strlen(word); i < length; i++)
{
hash_value = (hash_value << 2) ^ word[i];
}
return hash_value % HTSize; //N is size of hashtable
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
input = fopen(dictionary, "r");
if (input == NULL)
{
printf("Couldn't open dictionary");
return false;
}
//Creates a pointer from word pointing to NULL
char *word = NULL;
while (fscanf(input, "%s", word) == 1)
{
//For each word in the dictionary, allocate mem and create a new node, check pointer is NULL
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
printf("Could not allocate memory");
return false;
}
else
{
//Copy the word stored in the buffer to the new node and initialize the nodes value fields
strcpy(new_node->word, word);
new_node->next = NULL;
// Calculates hashcode of word in buffer using hash function ready for insertion into hashtable
unsigned int hash_code = hash(word);
// Initializes head to point to hashtable index/bucket
node *head = hashtable[hash_code];
// If no node in the Singly-Linked-List, add a new node
if (head == NULL)
{
hashtable[hash_code] = new_node;
word_count++;
}
else // If already a node present, re-arrange pointers to not orphan memory
{
new_node->next = hashtable[hash_code];
hashtable[hash_code] = new_node;
word_count++;
}
}
}
fclose(input);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return word_count;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
node *head = NULL;
node *cursor = head;
while (cursor != NULL)
{
node* tmp = cursor;
cursor = cursor->next;
free(tmp);
} return true;
}
// Returns true if word is in dictionary else false
bool check(const char *word)
{
//declares a string to hold a word converted to lowercase for hashing
char tmpword[LENGTH+1];
int n = strlen(word);
for(int i = 0; i < n+1; i++)
{
tmpword[i] = tolower(word[i]);
}
tmpword[LENGTH] = '\0';
// Create temp variable to house and locate hash value
int hash_code = hash(word);
//Search for a word in the linked list, linked to hashtable element
if (hashtable[hash_code] == NULL)
{
return false;
}
else if (hashtable[hash_code] != NULL)
{
//Create a node cursor pointing to 1st node in hashtable
node *cursor = hashtable[hash_code];
while (cursor != NULL)
{
if (strcasecmp(cursor->word, word) == 0)
{
return true;
}
else
{
cursor = cursor->next;
}
}
} return false;
}