So I finally finished my code and received 20 errors when attempting to compile, after my first attempt fixing the errors I tried again and received 15 errors, once more and received 17, and now am consistenly getting 20 again and I cannot figure out what to do although I may have an idea why it won't work. Here is my code:
// Implements a dictionary's functionality
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "dictionary.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 = 676;
// Hash table
node *table[N];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
// TODO
unsigned int y = hash(word);
node *cursor = table[y];
int match;
//
while(cursor != NULL)
{
char *word2 = cursor->word;
//
match = strcasecmp(word,word2);
if(match == 0)
{
return true;
}
else
{
cursor = cursor->next;
word++;
}
}
return false;
}
//hash function sourced and adapted from https://twpower.github.io/160-hash-table-implementation-in-cpp-en
// Hashes word to a number
unsigned int hash(const char *word)
{
//creates a hash seed value of 401 then loops through the words until NUL
int hash = 401;
while (*word != '\0')
{
//shifts hash 4bits left (multiplies by 16)
//takes the int value of the char and converts it to uppercase
//changing % MAX_TABLE to % table[N]
hash = ((hash << 4) + toupper((int)(*word))) % table[N];
word++;
}
return hash;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
unsigned int total = 0;
// Opens dictionary and reads
FILE *dict = fopen(dictionary, "r");
{
char newword[46];
//Returns false if dictionary does not open
if (!dict)
{
return false;
}
//Loops through the file as long as it doesn't reach EOF
while((fscanf(dict, "%s", newword) != EOF))
{
//creates an int variable for the int returned from the hash function
unsigned int x = hash(newword);
//allocates memory for a new node n and checks to see if there is enough memory
node *n = malloc(sizeof(node));
if(n == NULL)
{
return false;
}
//copies the current word into the word index of the n node struct
strcpy n->word, newword;
{
return 0;
}
n->next = NULL;
//inserting into hash table, new node into linked list
//Do I need to change table[N] to table[x] since x is hashcode?
if(x == NULL)
{
table[N] = x;
table[N]->next = n;
n->next = NULL;
}
else
{
n->next = table[N];
table[N]->next = n;
}
total++;
}
}
return true;
return total;
fclose(dict);
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
// returns the unsigned int total from load function
//cannot figure out how to access total from
return total;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// Will this work without the for? Should I seperate loops?
for(int i = 0; i < table[N]; i++)
{
while(cursor->next != NULL)
{
cursor = N;
int temp = cursor;
cursor = cursor->next;
free(temp);
}
return true;
}
else
{
return false;
}
}
As far as the errors:
dictionary.c:37:17: error: implicit declaration of function 'strcasecmp' is invalid in C99 [-Werror,-Wimplicit-function-declaration] match = strcasecmp(word,word2);
Which I think is because I only saw strcmp in <string.h> but when researching it said strcasecmp would be int this library too.
dictionary.c:62:54: error: invalid operands to binary expression ('int' and 'node *' (aka 'struct node *')) hash = ((hash << 4) + toupper((int)(*word))) % table[N]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~
dictionary.c:94:23: error: expected ';' after expression strcpy n->word, newword; ^ ;
Expects ; after strcpy for some reason.
dictionary.c:94:27: error: expression result unused [-Werror,-Wunused-value] strcpy n->word, newword; ~ ^~~~
n->word is unused
dictionary.c:101:22: error: comparison between pointer and integer ('unsigned int' and 'void *') [-Werror] if(x == NULL) ~ ^ ~~~~
dictionary.c:103:30: error: incompatible integer to pointer conversion assigning to 'node *' (aka 'struct node *') from 'unsigned int' [-Werror,-Wint-conversion] table[N] = x; ^ ~
dictionary.c:94:17: error: expression result unused [-Werror,-Wunused-value] strcpy n->word, newword; ^~~~~~
strcpy unused
dictionary.c:94:33: error: expression result unused [-Werror,-Wunused-value] strcpy n->word, newword; ^~~~~~~
newword unused
dictionary.c:103:21: error: array index 676 is past the end of the array (which contains 676 elements) [-Werror,-Warray-bounds] table[N] = x; ^ ~
I know is should be 675 since the array will begin at 0 but not sure where the error occurs.
dictionary.c:22:1: note: array 'table' declared here node *table[N]; ^
dictionary.c:104:21: error: array index 676 is past the end of the array (which contains 676 elements) [-Werror,-Warray-bounds] table[N]->next = n; ^ ~
dictionary.c:22:1: note: array 'table' declared here node *table[N]; ^
dictionary.c:109:31: error: array index 676 is past the end of the array (which contains 676 elements) [-Werror,-Warray-bounds] n->next = table[N]; ^ ~
dictionary.c:22:1: note: array 'table' declared here node *table[N]; ^
dictionary.c:110:21: error: array index 676 is past the end of the array (which contains 676 elements) [-Werror,-Warray-bounds] table[N]->next = n; ^ ~
dictionary.c:22:1: note: array 'table' declared here node *table[N]; ^
dictionary.c:125:12: error: use of undeclared identifier 'total' return total; ^
Cursor and total have been defined in other functions and I am trying to access them in another function where they were not defined and U think this is the issue just not sure how to fix it at this point. The rest of the errors are essentially repeat errors I believe.
dictionary.c:132:22: error: ordered comparison between pointer and integer ('int' and 'node *' (aka 'struct node *')) [-Werror] for(int i = 0; i < table[N]; i++) ~ ^ ~~~~~~~~
dictionary.c:134:15: error: use of undeclared identifier 'cursor' while(cursor->next != NULL) ^
dictionary.c:136:13: error: use of undeclared identifier 'cursor' cursor = N; ^
dictionary.c:137:24: error: use of undeclared identifier 'cursor' int temp = cursor; ^
dictionary.c:138:13: error: use of undeclared identifier 'cursor' cursor = cursor->next; ^
dictionary.c:138:22: error: use of undeclared identifier 'cursor' cursor = cursor->next;
If anyone could help me with the error and point out anything else you see that needs improvement that would be great! Updated Code:
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <strings.h>
#include <stdlib.h>
#include "dictionary.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 = 676;
// Hash table
node *table[N];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
// TODO
unsigned int y = hash(word);
node *cursor = table[y];
int match;
//
while(cursor != NULL)
{
char *word2 = cursor->word;
//
match = strcasecmp(word,word2);
if(match == 0)
{
return true;
}
else
{
cursor = cursor->next;
word++;
}
}
return false;
}
//hash function sourced and adapted from https://twpower.github.io/160-hash-table-implementation-in-cpp-en
// Hashes word to a number
unsigned int hash(const char *word)
{
//creates a hash seed value of 401 then loops through the words until NUL
int hash = 401;
while (*word != '\0')
{
//shifts hash 4bits left (multiplies by 16)
//takes the int value of the char and converts it to uppercase
hash = ((hash << 4) + toupper((int)(*word))) % N;
word++;
}
return hash;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
//uses int t as a parameter to be passed to another function with the int total
unsigned int total(unsigned int t)
{
t = 0;
}
{
// Opens dictionary and reads
FILE *dict = fopen(dictionary, "r");
{
char newword[46];
//Returns false if dictionary does not open
if (!dict)
{
return false;
}
//Loops through the file as long as it doesn't reach EOF
while((fscanf(dict, "%s", newword) != EOF))
{
//creates an int variable for the int returned from the hash function
unsigned int x = hash(newword);
//allocates memory for a new node n and checks to see if there is enough memory
node *n = malloc(sizeof(node));
if(n == NULL)
{
return false;
}
//copies the current word into the word index of the n node struct
strcpy n->word, newword;
{
return 0;
}
n->next = NULL;
//inserting into hash table, new node into linked list
if(x == NULL)
{
table[x] = x;
table[x]->next = n;
n->next = NULL;
}
else
{
n->next = table[x];
table[x]->next = n;
}
t++;
}
}
return true;
return total;
fclose(dict);
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
// returns the unsigned int total from load function
//cannot figure out how to access total from
return total;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for(int i = 0; i < N - 1; i++)
{
node *cursor = malloc(sizeof(node));
while(cursor->next != NULL)
{
cursor->next = table[N - 1];
node *temp = malloc(sizeof(node));
temp = cursor;
cursor = cursor->next;
free(&temp);
}
free(&cursor);
return true;
}
return false;
}