I have a few questions about speller, both about how the program operates and how I should begin the start debugging and testing a program of this complexity. My first question involves why you only need to allocate memory for certain nodes. It seems that the transfer node (you will see in my code below) requires allocating memory because you copy data into and later out of this node, yet other nodes (which I have concluded from looking at other people's code) does for some reason not require allocating memory. Is that because they are just pointers or something? I'm not sure. My second question revolves around what you need pointers for when inserting. It seems the walkthrough on CS50 recommends inserting at the beginning of a node, which would require more various pointers, because you don't want to "lose" the beginning of the node. My code inserts at the end of node, which does not require so many pointers. Now that my two conceptual questions are out of the way, I wonder how I'm supposed to debug a program this complex. For recover you could start with something like listing how many files are in the raw card to make sure you are reading correctly, but I'm not sure how I would start with something more elementary for this. Anyway, thanks for reading and below is my code.
// Implements a dictionary's functionality
#include <stdbool.h>
#include "dictionary.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <stdint.h>
// 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)
{
// TODO
int i;
i = hash(word);
node *current = table[i];
while (current != NULL)
{
if (strcasecmp(word, current -> word) == 0)
{
return true;
}
current = current -> next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO
int a = (word[0] -65);
return a;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// TODO
FILE *load = fopen(dictionary, "r");
if (load == NULL)
{
printf("There has been an error loading dictionary \n");
return false;
}
char word[LENGTH + 1];
while (fscanf(load,"%s",word) != EOF)
{
node *transfer = malloc(sizeof(node));
strcpy (transfer -> word, word);
transfer -> next = NULL;
int wordhash = hash(word);
while (transfer != NULL)
{
table[wordhash] = transfer;
table[wordhash] -> next = NULL;
table[wordhash] = table[wordhash] -> next;
}
}
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
// TODO
int total = 0;
for (int i = 0; i < N; i++)
{
while (table[i] != NULL)
{
total ++;
}
}
return total;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// TODO
for (int i = 0; i < N; i++)
{
while (table[i] != NULL)
{
node *tmp = table[i];
table[i] = table[i] -> next;
free(tmp);
}
if (table[i] == NULL)
{
free(table[i]);
}
}
return true;
}