0

First time posting a question but I have been struggling with this issue for about two weeks now.

All words in the text file with capital letters are showing up as misspelled.

I am also seeing an issue where strcmp() seems to not return 0 for capitalized words. When this problem occurs, my check function seems to run strcmp nonstop but eventually exits. (I am guessing this is because my load is not properly pointing the last node in the linked list to NULL but am not entirely sure.)

Any advice would be extremely helpful. Thanks in advance!

Here are my check and load function as well as the hash function I am using.

/**
 * dictionary.c
 *
 * Computer Science 50
 * Problem Set 5
 *
 * Implements a dictionary's functionality.
 */

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

#include "dictionary.h"
#include "hash.h"

#define BUCKETS 1000

//creates global struct node pointers for use in all functions and points them to null
node* hashtable[BUCKETS] = {NULL};

//defines a variable called counter to determine how many words are being loaded into dictionary
int counter = 0;

/**
 * Returns true if word is in dictionary else false.
 */
bool check(const char* word)
{
    //convert word to lower case

    int string_length = strlen(word);
    char* hash_word = malloc(sizeof(string_length));
    int i = 0;
    for (i = 0; i < string_length; i++)
    {
        if (isupper(word[i]))
        {
            hash_word[i] = tolower(word[i]);
        }
        else
        {
            hash_word[i] = word[i];
        }
    }
    int d = hash(hash_word) % BUCKETS;

    //traverse linked list comparing words
    node* cursor = hashtable[d];
    while (cursor != NULL)
    {
        if (strcmp(cursor->word, word) == 0)
        {
            return true;
        }
        //using this to see if strcmp is returning 0
        int temp2 = strcmp(cursor->word, word);
        printf("%i\n", temp2);        
        cursor = cursor->next;
    }

    return false;

}

/**
 * Loads dictionary into memory.  Returns true if successful else false.
 */
bool load(const char* dictionary)
{

    //opens dictionary file to read
    FILE* fp = fopen(dictionary, "r");
    //checks if file open is successful
    if (fp == NULL)
    {
        printf("Could not open dictionary.\n");
        return false;
    }

    //Checks whether pointer to file has reached the end of the file.
    while (!feof(fp))
    {
        /*creates a node pointer called new_node that points to a point in memory the size of node
        this will be used to store words from the dictionary*/
        node* new_node = malloc(sizeof(node));
        if (new_node == NULL)
        {
            printf("Could not allocate memory to new_node.\n");
            return false;
        }

        //node* head = NULL;

        //checks if scanf is at end of file, if not scan word into node pointer
        //reads in words from the dictionary into the node new_node is pointing to and assigns the scanned string to word
        if (fscanf(fp, "%s", new_node->word) != EOF)
        {
            //creates an integer (index) called hash_int that stores the hashed integer
            int hash_int = hash(new_node->word) % BUCKETS;
            //temp
            //printf("%s, %i\n", new_node->word, hash_int);

            /*insert word into bucket at index using linked list (remember hashtable[i] is a pointer)
            if hashtable pointer is currently NULL*/
            if (hashtable[hash_int] == NULL)
            {
                //sets hashtable pointer to point to what new_node is pointing to
                hashtable[hash_int] = new_node;
                //head = hashtable[hash_int];
                //sets new_node's next pointer to be NULL
                hashtable[hash_int]->next = NULL;
                counter++;
            }
            else
            {
                new_node->next = hashtable[hash_int];
                hashtable[hash_int] = new_node;
                counter++;
            }
        }

    }

    return true;
}

/**
 * Returns number of words in dictionary if loaded else 0 if not yet loaded.
 */
unsigned int size(void)
{
    //temp
    printf("%i\n", counter);
    //return number of words counted
    return counter;
}

/**
 * Unloads dictionary from memory.  Returns true if successful else false.
 */
bool unload(void)
{
    // TODO fourth
    return false;
}

Hash Code (using djb2)

// File: hash.h
// Description: Includes a number of sample hash functions.
// 
//! This is some utilites for CS23 search engine project ( or general case)
//! \brief implementation of the hash
//!        originally from http://www.cse.yorku.ca/~oz/hash.html
//! Hash functions are not randomly designed, there are theories behind.
//! read the above web page for details.

#include <string.h>
#include <stdlib.h>


//! this one is called djb2
unsigned long hash(char* str) {
  unsigned long hash = 5381;
  int c;
  while ((c = *str++) != 0)
    hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
  return hash;
}

1 Answer 1

1

I stopped at this point:

strcmp(cursor->word, word)

You are creating a new hash_word that is all lower case, but you are then trying to find word in your hashtable. Shouldn't you be trying to find hash_word?

1
  • Saw this and immediately face palmed. Thank you for the help! Fixing this solved my issue of capital letters! Still running into an issue where strcmp() seems to return a value that is not 0 but progressively gets smaller but I will work on debugging this on my own while working on unload!
    – Invysti
    Commented Oct 25, 2016 at 2:34

You must log in to answer this question.

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