0

So currently I'm working on speller and I suspect that there's a mistake(s) in load(). When I run my code it does load without an error message and correctly checks some words successfully and fails to check some words. I've been looking at my code for a couple of days now and I fail to see where my code doesn't make sense.

//global variables
int counter = 0;
sllnode *headp[10000];
sllnode *hashtable[10000];
int key;

bool load(const char *dictionary)
{
       // TODO
    //opens dictionary
    FILE *file = fopen(dictionary, "r");
    if(file == NULL)
    {
        printf("Failed to open file.\n");
        return false;
    }
    //starts to load
    else
    {
        //char array
        char word[LENGTH + 1];

        while(fscanf(file, "%s", word) != EOF)
        {
            //hash word
            key = hash_word(word);

            //checks if bucket is empty
            if(hashtable[key] == NULL)
            {
                hashtable[key] = create(word);
                headp[key] = hashtable[key];
                counter++;
            }

            //if bucket is not empty
            else if(hashtable[key] != NULL)
            {
                hashtable[key] = insert(&hashtable[key], word);
                headp[key] = hashtable[key];
                counter++;
            }
            //error
            else
            {
                fclose(file);

                return false;
            }
        }
        fclose(file);
        //success
        return true;
    }

    fclose(file);

    return false;
}

//creates list
sllnode* create(char word[])
{

sllnode *node = malloc((sizeof(sllnode)));
if(node == NULL)
{
    unload();
    printf("Memory error in creating list\n");
    return false;
}

strcpy(node->string, word);

node->next = NULL;

return node;
}

//insert node
sllnode* insert(sllnode *head[], char word[])
{
sllnode *node = malloc((sizeof(sllnode)));
if(node == NULL)
{
    unload();
    printf("Memory error in creating list\n");
    return false;
}

strcpy(node->string, word);

node->next = headp[key];

return node;
}

//hash function
unsigned int hash_word(const char* word)
 {
     unsigned long hash = 5381;

 for (const char* ptr = word; *ptr != '\0'; ptr++)
 {
     hash = ((hash << 5) + hash) + tolower(*ptr);
 }

 return hash % 10000;
 }
 //hash fuction is taken from github.com/hathix/cs50-section/blob/master/code/7/sample-hash-functions/good-hash-function.c

I've included all the fuctions for load() to work

1

Looks a bit unorganised, but I cannot spot any obvious mistake.

For a hashtable, you don't need any headp array. You seem to keep it at the same values as hashtable anyway.

Usage of a global key variable is somewhat scary (unnecessarily wide scope). There's no need for that to be global, only the hashtable and probably a word counter should be.

In load, else if(hashtable[key] != NULL) could just be else, since a pointer can only be NULL or not NULL, there's no third way.

Your last two lines in load cannot be reached, as in all paths you would have returned before.

insert has a pretty weird signature, and you don't use its first parameter at all. I think I get what you meant, as I did about the same, something like

node->next = *head; // instead of = headp[key];
*head = node;       // updating the list head

which is then used without the need for an assignment in load.

You must log in to answer this question.

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