0

I'm stuck on Pset5, Speller. My code all compiles correctly, and when run on the Lala Land example, provides the same output as the staff solution (albeit mine runs more slowly). But, check50 still shows mainly wrong:

:) dictionary.c, dictionary.h, and Makefile exist
:) speller compiles
:( handles most basic words properly
    expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( handles min length (1-char) words
    expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( handles max length (45-char) words
    expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( handles words with apostrophes properly
    expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( spell-checking is case-insensitive
    expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:( handles substrings properly
    expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:| program is free of memory errors
    can't check until a frown turns upside down

I've looked at questions with a similar problem and have tried running the code with a one word dictionary as both the dictionary and the text. I've also tried a text of 26 lines, with one letter on each line (a->z). In each case, the output line 'Words in Text' shows one fewer word than the actual number of words in the text. Could this be the problem? I don't see why this could be the error, though, because nothing in the dictionary.c file affects this 'words in text' count..?

For example, this is the output when I run ./speller texts/Untitled1, where Untitled1 is 26 lines with a->z, one letter per line:

WORDS MISSPELLED:     23
WORDS IN DICTIONARY:  143091
WORDS IN TEXT:        25
TIME IN load:         0.03
TIME IN check:        0.01
TIME IN size:         0.00
TIME IN unload:       0.00
TIME IN TOTAL:        0.04

Here is my code:

// Implements a dictionary's functionality

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

#include "dictionary.h"

void copy_string(char *target, char *source);
int word_count = 0;

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

// 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)
{
    int key = hash(word);

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

// Hashes word to a number
unsigned int hash(const char *word)
{
    unsigned int hash_value = 0;
    for (int i = 0; word[i] != '\0'; i++)
        {
            hash_value = tolower(word[i]);
        }
        return hash_value % N;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    //fopen dictionary - > creates file
    FILE *dict = fopen (dictionary, "r");
    if (dict == NULL)
    {
        //check if loaded correctly using NULL. If null return false.
        printf("Could not open dictionary.\n");
        return false;
    }
    //initialise hash table, with it initially blank
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }

    //create character array of length LENGTH for individual words to go in
    char word[LENGTH + 1];
    //repeat below for each of the words in the dictionary
    while (fscanf(dict, "%s\n", word) != EOF)
    {
        //create new node into which to put the new word and add 1 to the word count
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL)
        {
            return false;
        }
        else
        {
            //copies the word into the new node
            strcpy(new_node->word, word);
            //figures out the hash for the word
            int h = hash(word);
            //if nothing in the hash table at the hash value index
            //puts the new node at that index, with the next pointer as NULL
            //(there are no other vaulues in that table yet)
            if(table[h] == NULL)
            {
                new_node->next = NULL;
                table[h] = new_node;
            }
            //if already something in the hashtable, we point the new node to
            //the first item in the hashtable at that index
            //then set the first item to be the new node.
            else
            {
                new_node->next = table[h];
                table[h] = new_node;
            }
            word_count ++;
        }

    }
    fclose(dict);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    //gives the number of words in the dictionary
    if (word_count > 0)
    {
        return word_count;
    }
    else
    {
        printf("Empty dict, or no dict loaded\n");
        return 0;
    }
}

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

        while (cursor2 != NULL)
        {
            //creates a temp node
            node *temp = cursor2;
            cursor2 = cursor2->next;
            free(temp);
        }

        table[i] = NULL;
    }
    printf("successful unload. \n");
    return true;
}

1

uhhuh.....

Is it possible that something is being printed that shouldn't???

printf("successful unload. \n");
  • 1
    Cliff, I'm embarrassed to say that, yes, that's the problem... Thank you! – David S Aug 24 '20 at 23:46
  • Hopefully, that head slap didn't leave too big a bruise! ;-) Don't worry. We all do something like that, more often than we like to admit! ;-D – Cliff B Aug 25 '20 at 0:12

You must log in to answer this question.

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