0

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
3
  • Are you sure this is the current code? It contains a number of compile errors. Also, can you post your .h file too?
    – Cliff B
    Oct 8 '18 at 6:20
  • Yes, this is my current code. I've also posted my .h file above. Thanks
    – Prav Elan
    Oct 10 '18 at 11:34
  • I'm not sure if there are any compile errors because when I ran 'make speller' through the IDE compiler, it compiled with no issues.
    – Prav Elan
    Oct 10 '18 at 11:37
0

Assuming this is the code you use, your while(hashTable[j] != NULL) in unload might be either not entered at all or an infinite loop (as you never change the value of hashTable[j] within the loop). Remove it, your while (cursor != NULL) is enough.

1
  • Okay, I get where I went wrong now. Thanks for pointing out, the code works now
    – Prav Elan
    Oct 10 '18 at 11:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .