0

I have been trying to figure out the issue with my code for speller, but cant seem to find where the problem is. I have an intuition that it is somewhere in the check or Hash function. The program doesn't print out the results, might be stuck in some sort of loop.

I like struggling through these problems for hours lool, but any small tip would be appreciated!

// Implements a dictionary's functionality
    #include <stdbool.h>
    #include <stdio.h>
    #include "dictionary.h"
    #include <stdlib.h>
    #include <string.h>
    #include <strings.h>
    #include <ctype.h>

      // Represents a node in a hash table
        typedef struct node
        {
            char word[LENGTH + 1];
            struct node *next;
        }
        node;
      // Variable Declarations!!
        const unsigned int N = 5381;
        int num_word;
        char temp_word[LENGTH + 1];
        // Hash table
        node *table[N];
        node * temp;
        node * tracker;
      // Returns true if word is in dictionary else false
      bool check(const char *word)
      {
         char new_word[LENGTH + 1];
       // lower case of all the letter
        for(int i = 0 ; i < strlen(word); i++)
         {
            new_word[i] = tolower(word[i]);
         }
        // accesing hash value of the word for spell check and creating a pointer variable to iterate thought the linked list
        int link_index =  hash(new_word);
        struct node *find =  table[link_index];

        while(find != NULL)
        {
            if(strcasecmp(word , find->word) != 0 )
            {
                find = find -> next;
            }

            if(strcasecmp(word , find->word) == 0 )
            {
                return true;
            }
        }
            return false;
     }
       // Hashes word to a number by - Dan bernstein
        unsigned int hash(const char *word)
        {
            unsigned int hash = 5381;
            int c;
            while ((c = *word++))
                hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
            return hash % N;
        }
      // Loads dictionary into memory, returning true if successful else false
      bool load(const char *dictionary)
        {
        // Open the dictionary file
            FILE* DIC = fopen(dictionary, "r");
             if (DIC == NULL)
             {
                return 1;
             }
        // Iterate through the index in my hash table and setting linked list heads to NULL
            for(int i = 1 ; i < N; i++)
             {
                table[i] = NULL;
             }
        // Looping through each word in the dictionary until i reach the end of the flle
            while(fscanf(DIC , "%s", temp_word) != EOF)
            {
        // Create a new node
             node *n =  malloc(sizeof(node));
                if(n == NULL)
              {
                  return 1;
              }
                // copy my current tempory word into the node
              {
                   strcpy(n -> word , temp_word);
                   n -> next = NULL;
                   num_word++;
              }
        // Hash the current word and storing the index into a variable link_index
             int link_index = hash(n -> word);
        // insert first word into the beginning of the linked list
             if(table[link_index] == NULL)
              {
                table[link_index] = n;
              }
        // if there is already a word in the beginning of the link list moved new node to be at the beginning of the linked list
             if(table[link_index] != NULL)
              {
                n -> next =  table[link_index];
                table[link_index] = n;
              }
            }
         return true;
        }
        // Returns number of words in dictionary if loaded else 0 if not yet loaded
        unsigned int size(void)
        {

            return num_word;
        }
       // Unloads dictionary from memory, returning true if successful else false
        bool unload(void)
        {
       // variable tracking the linked list that i am iterating through
        for(int i = 0 ; i < N; i++)
        {
            tracker = table[i];
            while(tracker != NULL)
            {
                 temp = tracker;
                 tracker = tracker -> next;
                 free(temp);
            }
            return true;
        }
            return false;
        }

1 Answer 1

0

Did you know there is an else one can use on an if? Some of your issues could be solved by using it ;-)

Your code

        // insert first word into the beginning of the linked list
             if(table[link_index] == NULL)
              {
                table[link_index] = n;
              }
        // if there is already a word in the beginning of the link list moved new node to be at the beginning of the linked list
             if(table[link_index] != NULL)
              {
                n -> next =  table[link_index];
                table[link_index] = n;
              }

first checks whether the linked list is empty. If so, installs the node.

But then it checks again whether the list is non-empty. At this point, the list is always non-empty. If you now do n -> next = table[link_index];, you have your node link to itself, creating an infinite loop.

This problem could be solved by turning the second if into an else. If you want it with less code and as correct, of the whole if () {} if () {} structure, delete everything but the

            n -> next =  table[link_index];
            table[link_index] = n;

This code works for first node as for non-first node, no if required.

You could also use an else in check, but this time it's not breaking anything.

BTW: for(int i = 1 ; i < N; i++) looks wrong, not just for beginning with 1. You don't need that loop (because global variables are always initialised, if implicitly then to all bytes zero).

unload should not return false, you have no way to check if something went wrong. You shouldn't return in that loop either.

7
  • Thanks! Very helpful was able to correct the issues and now the code runs but i think my check function is over-flagging the number of misspelled words
    – mo_coder
    Feb 14, 2020 at 4:11
  • Therefore the code is still failing check50
    – mo_coder
    Feb 14, 2020 at 4:14
  • Null terminator missing in your lower-case copy maybe?
    – Blauelf
    Feb 14, 2020 at 6:36
  • Haha, forgat that strlen() does copy the null terminator! all checks working except for: free of memory errors.
    – mo_coder
    Feb 14, 2020 at 15:36
  • 552 bytes in 1 blocks are still reachable in loss record 1 of 1: (file: dictionary.c, line: 67)
    – mo_coder
    Feb 14, 2020 at 15:37

You must log in to answer this question.

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