0

When I run the program, all words are considered misspelled. I can't figure out where the problem is. Can someone please help me?

It also says that my program is free of memory errors - can't check until a frown turns upside down.

// Represents number of buckets in a hash table
#define N 26

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

// Represents a hash table
node *hashtable[N];

// Word counter
int wordcount = 0;

// Hashes word to a number between 0 and 25, inclusive, based on its first letter
unsigned int hash(const char *word)
{
    return tolower(word[0]) - 'a';
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Initialize hash table
    for (int i = 0; i < N; i++)
    {
        hashtable[i] = NULL;
    }

    // Open dictionary
    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        unload();
        return false;
    }

    // Buffer for a word
    char word[LENGTH + 1];

    // Insert words into hash table
    while (fscanf(file, "%s", word) != EOF)
    {
        // We want to malloc a node for every word we scan
        node *new_node = malloc(sizeof(node));

        // Making sure that the pointer to that node doesn't point to NULL
        if (new_node == NULL)
        {
            unload();
            return false;
        }

        else

        // Copy word into a node
        strcpy(new_node->word, word);

        // Insert word into a linked list
        int i = hash(word);

        // If this is the first word in the bucket
        if (hashtable[i] == NULL)
        {
            hashtable[i] = new_node;
            new_node->next = NULL;
        }
        else
        {
            new_node->next = hashtable[i];
            hashtable[i] = new_node;
        }

        wordcount++;
    }


    // Close dictionary
    fclose(file);

    // Indicate success
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    return wordcount;
    return 0;
}

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // Traversing linked list
    int i = hash(word);
    node *cursor = hashtable[i];

        while (cursor !=NULL)
        {
            // Compare 2 strings
            if (strcasecmp(cursor->word,word) == 0)
            {
                return 0;
            }
            else

            cursor = cursor->next;
        }
    return false;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    for (int i = 0; i < N; i++)
    {
        node *cursor = hashtable[i];
        while (cursor != NULL)
        {
            node *temp = cursor;
            cursor = cursor->next;
            free(temp);
        }
        return true;
    }
    return false;
}
1
  • "can't check until a frown turns upside down." just means that an earlier test has to pass before this test can be done.
    – Cliff B
    Commented Jul 22, 2019 at 22:52

1 Answer 1

3

Well, this was easy, if not hidden right out in the open. ;-) Look at the core piece of the check code:

// Compare 2 strings
        if (strcasecmp(cursor->word,word) == 0)
        {
            return 0;
        }

So, I'm guessing that you're not aware that false is represented by 0 and true by any non-zero integer?

Easy mistake to make for new programmers. There's a parallel best practice that says that a program returns 0 when it completes successfully, and a non-zero number to represent an error specific to the program (user defined.) Don't confuse return 0; with return true;

This is also a good lesson that programmers should ALWAYS return only true or false when a function is returning a bool. True and false state exactly what's intended, while a number can be confused.

Interestingly, all of the functions in the issomething() family, like isalpha, isdigit, etc., return ints, not bools. Yet, each return result can be treated as a bool. Each returns a different integer when true, something I believe has its roots in assembler programming and the use of system registers. (Each value returned is a power of 2, or a different binary bit in a register. It allowed for setting multiple register flags when something could be more than one thing, like being both isalpha and islower.) But, ALL of them return 0 when false.

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

2
  • Well, that was an easy fix! Thank you @CliffB! Just to make sure I understand things correctly, return 0 means false but return true also spits out 0?
    – dino
    Commented Jul 22, 2019 at 23:18
  • No. return true will spit out 1. Return false will spit out 0. Also, any integer other than 0 will evaluate as true. Remember, numbers and bools can be cast as each other.
    – Cliff B
    Commented Jul 22, 2019 at 23:41

You must log in to answer this question.

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