0

I am trying to debug and understand which part of my code is causing check() not to work. It's possible that the code maybe more complicated than needed but I was going to refactor it once I had a working solution. At this point of time I am not sure if my hashmap has generated correctly and if yes, then why check() isn't working.

Header Filers and Global Variables

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include "dictionary.h"

typedef struct node
{
char word[LENGTH+1];
struct node* next;
} node;

int* word_counter_ptr = NULL;
// Protoype for the Hash Function
 unsigned int stringToHash(const char *word);

// Variables to use for the hash map
int hash_val = -1;
//Hash Table Size
node *hashtable[HASH_TABLE_SIZE];

// Variable to hold state of dict
bool flag = false;

//variable to hold count of words
int word_counter = 0;

load()

bool load(const char *dictionary)
{ 

// Open the dictionary file in read mode.
FILE * file_ptr = fopen(dictionary,"r");
char buff[LENGTH+1];

//Reading words into a buffer.
 while(fgets(buff,LENGTH,file_ptr)!=NULL)
 {
    // Returns the hash table index based on the hash() of the word in the dictionary
    hash_val = stringToHash(buff);

    // Checking if the hashtable at index hash_val has any head pointers to a link list already. If not then
    // it creates a new node and calls it the head.
    if(hashtable[hash_val] == NULL)
    {
        node* head = malloc(sizeof(node));
        strcpy(head->word,buff);
        head->next = NULL;
        hashtable[hash_val] = head;
        word_counter++;
    }

    else if( hashtable[hash_val] != NULL)
    {

        node *new_node = malloc(sizeof(node));
        strcpy(new_node->word,buff);
        new_node->next = hashtable[hash_val];
        hashtable[hash_val] = new_node;
        word_counter++;
    }
 flag = true;
 }
if (flag == false)
{
    return false;
}
else{
    return true;
}

}

check()

bool check(const char *word)
{

int length_of_word = strlen(word);
char* word_lower_case = malloc(sizeof(length_of_word));

for(int i = 0,n = length_of_word;i < n;i++)
{   
    if(isupper(word[i]))
        word_lower_case[i] = tolower(word[i]);
    else
        word_lower_case[i] = word[i];
}
//Hashing the string that needs to be checked
hash_val = stringToHash(word_lower_case);

node* current = hashtable[hash_val];
while(current != NULL)

{
    if (strcmp(current->word,word_lower_case)==0)
    {
        return true;
    }
    else
    {
        current = current->next;
    }
}

return false;
}

#UPDATE

I added some print statements to my check() and it looks like the hash table does not load.

I created 2 small text files: test_dict.txt-

yes
no
how
life
super
dog

test_text.txt

 adsada
 dasdasdasda
 dasdaasda
 dog
 adasdasdasszcsd
 dasdasdas

Command I ran: ./speller test_dict.txt test_text.txt

bool check(const char *word) {

            int length_of_word = strlen(word);
            char* word_lower_case = malloc(sizeof(length_of_word));
            for(int i = 0,n = length_of_word;i < n;i++)
            {   
                if(isupper(word[i]))
                    word_lower_case[i] = tolower(word[i]);
                else
                    word_lower_case[i] = word[i];
            }

            printf("strlen of word is %lu \n",strlen(word));
            printf("strlen of word_lower_case is %lu \n",strlen(word_lower_case));

            //Hashing the string that needs to be checked
            hash_val = stringToHash(word_lower_case);
            printf("Hash Value is %i \n",hash_val);
            printf("Checking if hash_table has loaded..\n");
            printf("Value for dog should exist in 441\n");
            printf("Value for hashtable[441] is %s \n", hashtable[441]->word);



            return false;
        }

OUTPUT

MISSPELLED WORDS

        strlen of word is 6 
        strlen of word_lower_case is 6 
        Hash Value is 174 
        Checking if hash_table has loaded..
        Value for dog should exist in 441
        Value for hashtable[441] is (null) 
        adsada
        strlen of word is 11 
        strlen of word_lower_case is 11 
        Hash Value is 340 
        Checking if hash_table has loaded..
        Value for dog should exist in 441
        Value for hashtable[441] is (null) 
        dasdasdasda
        strlen of word is 9 
        strlen of word_lower_case is 9 
        Hash Value is 328 
        Checking if hash_table has loaded..
        Value for dog should exist in 441
        Value for hashtable[441] is (null) 
        dasdaasda
        strlen of word is 3 
        strlen of word_lower_case is 3 
        Hash Value is 441 
        Checking if hash_table has loaded..
        Value for dog should exist in 441
        Value for hashtable[441] is (null) 
        dog
        strlen of word is 9 
        strlen of word_lower_case is 9 
        Hash Value is 108 
        Checking if hash_table has loaded..
        Value for dog should exist in 441
        Value for hashtable[441] is (null) 
        adasdasda

        WORDS MISSPELLED:     5
        WORDS IN DICTIONARY:  6
        WORDS IN TEXT:        5
        TIME IN load:         0.00
        TIME IN check:        0.00
        TIME IN size:         0.00
        TIME IN unload:       0.00
        TIME IN TOTAL:        0.00
0

Some problems in check with word_lower_case. It is not allocated properly. length_of_word is declared int. sizeof an int is 4. So char* word_lower_case = malloc(sizeof(length_of_word)); allocates word_lower_case for 4 bytes. And since it is built char by char, it never gets a null terminator. That will give "unpredictable results" hereif (strcmp(current->word,word_lower_case)==0). It needs to be allocated for the same length as word (plus 1 for the null-byte!).

The test_dict.txt from the update is not created according to the rules, so it's hard to say what is wrong and what is right. It needs to be "sorted lexicographically, ", ie alphabetical. Also the check in the update has no strcmp and always returns false. Use debug50 or gdb with a small dictionary and a small text file to help you troubleshoot.

6
  • Thanks DinoCoderSaurus! I am going to make the changes you proposed. I think I may have found another bug in my code. stringToHash(buff) = 3 // When buff is dog stringToHash("dog") = 1 Any idea why? – Rushil Grover Feb 8 '17 at 8:18
  • stringToHash(buff) = 3 // When buff is dog v/s stringToHash("dog") = 1 – Rushil Grover Feb 8 '17 at 8:27
  • The debugging output shows stringToHash returns 441 for the word dog in the check function, so I'm not understanding your comment. I hope the info in my answer that was wrong (and has been edited out) did not confuse the issue. Sorry for that. – DinoCoderSaurus Feb 8 '17 at 12:41
  • I changed the value of my HASH_TABLE_SIZE to get smaller hash values to work with. If you try running this piece of code on your local machine, you can create a list that is lexicographically sorted and probably be able to reproduce my issue. Issue: stringToHash is returning a different value for the word 'dog' when its read from the dictionary as buff when compared to the value returned while reading the text file or passed as a string directly to the function. Hope this clears it out and thank your for your help so far! – Rushil Grover Feb 8 '17 at 18:40
  • There is no stringToHash function in the posted code. Have you gone through the function in the debugger to try to ascertain why it is returning different values for the presumed same input? And think about this from man fgets: If a newline is read, it is stored into the buffer. . Perhaps buff and "dog" differ by a newline! – DinoCoderSaurus Feb 8 '17 at 21:17
0

Can you provide me some information:

if (strcmp(current->word,word_lower_case)==0)

Before that if, can you run strlen on both current->word and word_lower_case? What is the result on a word that should match? You may need to create a fake story of only a few words and a fake dictionary of only a few words, and make sure the word "dog" is in both.

3
  • Okay. I think the problem is that the hash table is not loading correctly perhaps. I have edited my question – Rushil Grover Feb 8 '17 at 1:22
  • Have updated with some print statements and the information you requested. – Rushil Grover Feb 8 '17 at 1:44
  • So if I'm reading correctly, they should be matching up because the lengths are the same. I'll have to look closer later, as my first guess was wrong. :) – James Goldstein Feb 8 '17 at 1:54

You must log in to answer this question.

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