0

Hello Stack Exchange Team.

I am having an unusual issue that I am not sure how to tackle. I am working on the problem set speller. I have written all of my code into dictionary.c as instructed. I believe I am loading my dictionary into a hash table as required. That is to say in the load function I have placed printf statements in to observe all of the words being at least read, and presumably stored. The problem is I keep getting the error "text(birdman, bible, etc) wouldn't load".

This error is hard coded into speller.c and was pre-written and distributed to me. The instructions say not to touch speller.c. Is there something about the code I have written that I can look into that might be causing this error?

here is the code

// Implements a dictionary's functionality

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

#include "dictionary.h"

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

void destroy(node *n);

int words = 0;

// Number of buckets in hash table
const unsigned int N = 26;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    //variables to compare. node searches list, index is the returned hash value, index is the input words has value
    node *cursor;
    unsigned int index;

    index = hash(word);
    cursor=table[index];

    while(cursor->next!=NULL)
    {

        if(strcasecmp(cursor->word, word)==0)
        {
            return true;
            break;
        }
        else
        {
            cursor=cursor->next;
        }
    }

    // TODO
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    //DJB-2 aquired from "http://www.cse.yorku.ca/~oz/hash.html"
        unsigned long hash = 5381;
        int c;

        while ((c = *word++))//changed *str in orginal code to *word per cs50 code
            {
            hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
            }
        return hash%N;
    // TODO
    return 0;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    //variable declairations
    char buffer[45];
    node* temp;
    unsigned int index;

    //opens dictionary
    FILE *file = fopen(dictionary, "r");
    if (file==NULL)
    {
        printf("file cannot be read \n");
        return false;
    }

    //read file for words

    while(fscanf(file, "%s", buffer)!=EOF)
    {
        temp=malloc(sizeof(node));
            if(temp==NULL)
            {
                printf("not enough memory");
                return false;
            }

    //gets hash number from has function
        index=hash(buffer);

    //assigns temp node word the word in buffer
        strcpy(temp->word, buffer);

    //adds node to table
            temp->next=table[index];
            table[index]=temp;

        words++;
    }
    // TODO
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    if(words==0)
    {
       printf("Dictionary not loaded");
    }
    else
    {
        printf("Dictionary contains %i words: \n", words);
    }

    // TODO
    return 0;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    for(int i=0; i<N; i++)
    {
        destroy(table[i]);
    }
    // TODO
    return false;
}

void destroy(node *n)
{
   if(n->next!=NULL)
   {
       destroy(n->next);
   }
   free(n);
}

Thanks, Rob

0

The problem is in the unload() function and it's interaction with destroy(). The destroy() function depends on the node pointer passed to it not being NULL. What happens if table[i] is null? Then n->next in destroy() doesn't exist, causing a seg fault.

As for the text not loading, that looks like it might be because the file isn't where you're telling the program it is. All the texts are in the texts subdirectory (unless you moved them). Are you invoking with ./speller texts/birdman.txt or just ./speller birdman.txt?

There are other problems in the code, but you'll find them soon enough. Also, check the program requirements for size. Nowhere does the spec say to print anything anywhere. I'll let you figure out the rest. ;-)

Happy coding!

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

3
  • Thanks for the response. I will have to modify my destroy function. That is a good tip! as far as commandline arguments go, i have tried both variations you mentioned above. Neither works, or another way to say it is they both return the same fault. Ill start with fixing the destroy function and report back, but I am a little leary that ill be able to tell if destroy is fixed since I havne't been able to see it not work yet. Does that make sense? – Rob Watt Jun 26 '20 at 3:38
  • Try changing the unload function first. – Cliff B Jun 26 '20 at 3:44
  • I forgot to close this one out. in order to complete the project i did have to do some work on the hash function and a couple other areas, but it works very well now. thank you for the help! – Rob Watt Jul 9 '20 at 16:06

You must log in to answer this question.

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