0

I used strcasecmp for comparing the words case-insensitively. However, check50 showed that I failed the test for case-insensitivity. I believe that my programme treated foO, fOo, Foo, fOO, FoO, FOo and FOO as misspelled words. Is strcasecmp working? Or do I miss any point?

// Implements a dictionary's functionality

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

#include "dictionary.h"

// for tracking the no. of words
int n_word = 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 = 5381;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // TODO
    //create a cursor
    node *cursor = table[hash(word)];
    //check if the word is in dictionary
    while (true)
    {
        //if the cursor returns NULL, it means it reaches the end and hence break
        if (cursor == NULL)
        {
            break;
        }
        //if the word pointed to by the cursor and the word in the text are same, return true
        if (strcasecmp(word, cursor->word) == 0)
        {
            return true;

        }
        //else the cursor moves to the next word
        else
        {
            cursor = cursor->next;
        }
    }
    return false;
}

// Hashes word to a number by adopting djb2
//retrieved from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash(const char *word)
{
    // TODO
    unsigned long hash = N;
    int c;
    while ((c = *word++))
    {
        hash = ((hash << 5) + hash) + c;
    }
    return (hash % N);
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // TODO
    //open file
    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        return false;
    }
    //tmp is created to store words read from dictionary temporarily
    char tmp[LENGTH + 1];
    //scan file and if end of file, stop looping
    while (fscanf(file, "%s", tmp) != EOF)
    {
        //create a new node
        node *n = malloc(sizeof(node));

        //return false if the return value of n is NULL
        if (n == NULL)
        {
            return false;
        }
        //copy word into node using strcpy
        strcpy(n->word, tmp);
        n->next = NULL;
        unsigned long index = hash(tmp);
        //if null, it means it is the first node and hence skip to the next step to insert n
        // if not null, it means nodes already exist and the new n is inserted into the front of the list
        if (table[index] != NULL)
        {
            n->next = table[index];
        }
        table[index] = n;
        //for tracking the no. of word which is later returned by size()
        n_word += 1;

    }
    //as file is opened, close it after loading
    fclose(file);
    return true;
}

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

    return n_word;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // TODO

    node *tmp;
    for (int i = 0; i < N; i++)
    {
        node *cursor = table[i];
        //make tmp equal cursor
        tmp = cursor;

        while (true)
        {
            //if cursor points NULL, end loop
            if (cursor == NULL)
            {
                break;
            }
            //cursor first move to the next node
            //then tmp, which previously is set to equal cursor, is freed
            //tmp is set to be cursor
            else
            {
                cursor = cursor->next;
                free(tmp);
                tmp = cursor;
            }
        }
    }
    return true;
}

enter image description here

0

This if (strcasecmp(word, cursor->word) == 0) looks like it would fulfill the requirement as long as this node *cursor = table[hash(word)]; (specifically hash(word)) was also case insensitive. Alas, it is not; hash("foo") and hash("fOo") will return different values.

1
  • How would one fix that problem? Is there a function to read hash(word) case-insensitively? – Brandon Zemel Jun 11 '20 at 2:03

You must log in to answer this question.

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