0

I am attempting to complete week 5's "Speller" but it is not working. It compiles, but it seems that it does not check properly. My check function may be incorrect, but I cannot tell. I end up with "19190 Misspelled words" when it should be a lot lower. Thank you to whoever will help.

This is check50's output:

:) dictionary.c, dictionary.h, and Makefile exist
:) speller compiles
:( handles most basic words properly
    expected "MISSPELLED WORD...", not "MISSPELLED WORD..."
:( handles min length (1-char) words
    valgrind tests failed; rerun with --log for more information.
:( handles max length (45-char) words
    expected "MISSPELLED WORD...", not "MISSPELLED WORD..."
:( handles words with apostrophes properly
    expected "MISSPELLED WORD...", not "MISSPELLED WORD..."
:( spell-checking is case-insensitive
    expected "MISSPELLED WORD...", not "MISSPELLED WORD..."
:( handles substrings properly
    expected "MISSPELLED WORD...", not "MISSPELLED WORD..."

dictionary.c code:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include "dictionary.h"
#define HASHSIZE 65536


int dictionarysize = 0;
typedef struct node
    {
        char word[LENGTH + 1];
        struct node* next;
    }
    node;

    node* hashtable[HASHSIZE];

//
//credit for hashtable: https://www.reddit.com/r/cs50/comments/1x6vc8/pset6_trie_vs_hashtable/cf9nlkn

int hash(char* needs_hashing)
{
    unsigned int hash = 0;
    for (int i=0, n=strlen(needs_hashing); i<n; i++)
        hash = (hash << 2) ^ needs_hashing[i];
    return hash % HASHSIZE;
}
//

bool check(const char *word)
{
    char localwordvar[LENGTH + 1];

    for (int i = 0; i < strlen(word); i++)
       localwordvar[i] = tolower(word[i]);

    localwordvar[strlen(word)] = '\0';

    int head = hash(localwordvar);
    if (hashtable[head] == NULL)
        return false;

    node*cursor = hashtable[head];
    while (cursor != NULL)
    {
        if (strcasecmp(localwordvar, cursor->word) == 0)
            return true;
        cursor = cursor->next;
    }
    return false;
}


bool load(const char *dictionary)
{
    // TODO


    FILE* dicfile = fopen(dictionary, "r");
    if (dicfile == NULL)
        return false;

    char word[LENGTH + 1];

    while (fscanf(dicfile, "%s/n", word) != EOF)
    {
        dictionarysize += 1;

        node *new_word = malloc(sizeof(node));
        strcpy(new_word->word, word);
        int head = hash(word);

        if (new_word == NULL)
        {
            hashtable[head] = new_word;
            new_word->next = NULL;
        }
        else
        {
            new_word->next = hashtable[head];
            hashtable[head] = new_word;
        }
    }

    fclose(dicfile);
    return true;

}




unsigned int size(void)
{

     if (dictionarysize > 0)
        return dictionarysize;
    else
        return 0;
}


bool unload(void)
{
    int head = 0;
    while (head < HASHSIZE)
    {
        if (hashtable[head] == NULL)
            head++;

        else
        {
            while(hashtable[head] != NULL)
            {
                node* cursor = hashtable[head];
                hashtable[head] = cursor->next;
                free(cursor);
            }
            head++;
        }
    }


    return true;
}
1

The check() function as written simply doesn't work. The word is copied to local var word in check(), but the contents are never used or copied. Most of the work is being done on another local var localwordvar which contains garbage data.

The contents of word needs to be acted upon.

BTW, what happens if word contains a capital letter?

It looks like load has a couple of unrelated issues too, but I'll let you have a chance to find them first. ;-)

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

6
  • Alright, I added a for loop in check to add the contents of word into localwordvar and made sure it was all lower case. That seems to help. I have a question though. I thought the function strcasecmp did not take upper/lower case alphabet into account, therefore it did not matter whether or not the input was already set to lower case?
    – R_C
    Nov 7 '17 at 1:46
  • hehe, it doesn't matter. I didn't look quite that close at the code that far down after I found the main problem. However, if you're using strcasecmp, you could replace the whole for loop and the setting of the end of string marker with strcpy(). ;-)
    – Cliff B
    Nov 7 '17 at 1:59
  • If it's working now, could you accept the answer please? Otherwise, it'll sit in the unanswered question pool forever.
    – Cliff B
    Nov 7 '17 at 2:58
  • Sorry, I have been busy. I accepted it. Thank you so much for your help!
    – R_C
    Nov 9 '17 at 6:09
  • I'm sorry, could you please add the correct code? I'm having the same issue you had and I can't figure it out. Aug 27 '20 at 22:23

You must log in to answer this question.

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