Have I somehow altered ctype.h? - c

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dictionary.h"
#define HASH_SIZE 5
// prototype
int hash(char *word);
// counter
int counter;
// node
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
} node;
// hash table
struct node *hashtable[HASH_SIZE];
/*
* Returns true if word is in dictionary else false.
*/
bool
check(const char *word)
{
//make a writable word (palabra)
int len = strlen(word);
char palabra[len + 1];
//int i;
// make la palabra all lowercase letters
for ( int i = 0; i < len; i++)
{
if (isalpha(palabra[i]) || palabra[i] == '\'')
palabra[i] = tolower(word[i]);
}
//palabra[i] = (char) "\0";
// hash the word
int value = hash(palabra);
// let's look at the first node in the bucket
struct node *n;
if (hashtable[value] == NULL)
return false;
else
n = hashtable[value];
// iterate through the bucket to see if the word is there
while (strcmp(palabra, n->word) != 0 && n->next != NULL)
{
n = n->next;
}
// if the word is found, print true, else false
if ( strcmp(palabra, n->word) ==0 )
return true;
else
return false;
}
/*
* Loads dictionary into memory. Returns true if successful else false.
*/
bool
load(const char *dictionary)
{
// open the dictionary
FILE *dict = fopen(dictionary, "r");
if(dict == NULL)
{
printf("Could not open %s.\n", dictionary);
return false;
}
// set all values in the hash table to null
for(int i = 0; i < HASH_SIZE; i++)
{
hashtable[i] = NULL;
}
// set the counter to 0
counter = 0;
// iterate through the words in the dictionary
while (!feof(dict))
{
//declare a node
node *n = malloc( sizeof(node) );
// copy the word into the node
fscanf(dict, "%s", n->word);
// hash the word, baby!
int hash_value = hash(n->word);
// start saving addresses to the hashtable
n->next = hashtable[hash_value];
hashtable[hash_value] = n;
// that's one more!
counter++;
}
// testing
printf("Starting the test.\n");
for ( int i = 0; i < HASH_SIZE; i++)
{
struct node *q = hashtable[i];
while (q != NULL)
{
printf("%s\n", q->word);
q = q->next;
}
}
printf("Ending the test.\n");
fclose(dict);
return true;
}
/*
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int
size(void)
{
return counter;
}
/*
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool
unload(void)
{
// TODO
return false;
}
/*
* Returns a hash value for a word.
*/
int
hash(char *word)
{
// hash value and length of word
int value = 0;
int len = strlen(word);
// iterate through letters, adding ASCII values
for(int i = 0; i < len; i++)
{
int letter = (int) word[i];
value += letter;
}
// make sure the value is less than 100 & return
value = value%HASH_SIZE;
return value;
}
When I run my code, I receive this error message:
In file included from /usr/include/ctype.h:28:0,
from speller.c:10:
/usr/include/bits/types.h:31:1: error: expected '=', ',', ';', 'asm' or 'attribute' before 'typedef'
Does this mean that I have somehow managed to alter the ctype.h library? If so, how do I fix it?

Aha! Gordon, you solved it! I found some stray characters typed just above the #include that were causing the problem. Thanks!

Related

Cs50 pset5 - program crashing

I finished writing my code for speller. It compiles fine but the only output being printed is "Misspelled words". The words misspelled , words in text, words in dictionary does not get printed. I'm assuming its because the program crashes before then? Here is my code. If only I knew in which function or area my problem lies I might be able to fix it. Also, my hash function is to base hash indexes base on the first two letters of the word.
// Implements a dictionary's functionality
#include <ctype.h>
#include <stdbool.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dictionary.h"
int dsize = 0;
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// TODO: Choose 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
// hash word
int hashnumber = hash(word);
node *cursor = table[hashnumber];
// traversing linked list at that hash number
while(cursor != NULL)
{
if((strcasecmp(cursor->word, word) == 0))
{
return true;
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
int hash;
// TODO: Improve this hash function
for( int i = 97; i < 123; i ++)
{
hash = (i - 97) * 26;
// check asciivalue both uppercase and lowercase for first letter
if(word[0] == (char)i || word[0] == (char)(i - 32) )
{
for ( int j = 97; j < 122; j++)
{
// check asciivalue both uppercase and lowercase for second letter
if(word[1] == (char)j || word[1] == (char)(j - 32))
{
hash = hash + (j - 97);
}
}
}
}
return hash;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
for( int i = 0; i < N; i++)
{
table[i] = NULL;
}
FILE *input = fopen(dictionary, "r");
if (dictionary== NULL)
{
return false;
}
node *temp;
char word[LENGTH + 1];
while((fscanf(input, "%s", word)) != EOF)
{
temp = malloc(sizeof(node));
if(temp == NULL)
{
return false;
}
strcpy(temp->word, word);
int hashnumber = hash(word);
if (table[hashnumber] == NULL)
{
table[hashnumber] = temp;
}
else
{
temp->next = table[hashnumber];
table[hashnumber] = temp;
}
dsize++;
}
fclose(input);
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
return dsize;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
node *temp;
node *cursor;
for ( int i = 0; i < N; i++ )
{
cursor = table[i];
while(table[i] != NULL)
{
temp = cursor;
cursor = cursor->next;
free(temp);
}
if(cursor == NULL && i == (N - 1))
{
return true;
}
}
return false;
}

Check50 Errros: Not passing "handles substrings properly" tests. Check50 also can't check for a memory errors

I am working on Pset5 Speller. I made hashing function using the concept of binary numbers of base 26. So single alphabet words are stored in index 1-26, words containing apostrophes are stored in index 0 and the remaining are hashed using the first two alphabets. I tried to debug the code and run Valgrind on it still was unable to find the reason for failing of Substring tests any suggestions
// Implements a dictionary's functionality
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <cs50.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 = (26 * 26) + 26 + 1 ;
// Hash table
node *table[N];
int numberofwords = 0;
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
int index = hash(word);
node *checker;
checker = table[index];
while (checker != NULL)
{
int comp = strcasecmp(word, checker->word);
if (comp == 0)
{
return true;
}
else
{
checker = checker->next;
}
}
// TODO
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
int value = 0;
int length = strlen(word);
for (int i = 0; i < length; i++)
{
char c = word[i];
if (c == '\'')
{
value = 0;
return value;
}
}
if (length == 1)
{
value = tolower(word[0]) - 'a' + 1;
return value;
}
else
{
value = (26 * (tolower(word[1]) - 'a' + 1)) + (tolower(word[0]) - 'a' + 1);
return value;
}
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
//open dictionary and loop till EOF
char buffer[LENGTH + 1];
FILE *temp = fopen(dictionary, "r");
if (temp == NULL)
{
return false;
}
for (int i = 0; i < N; i++)
{
table[i] = NULL;
}
while (fscanf(temp, "%s", buffer) != EOF)
{
node *temp_node = malloc(sizeof(node));
if (temp_node == NULL)
{
return false;
}
strcpy(temp_node->word, buffer);
temp_node->next = NULL;
//hash the word
int locate = hash(buffer);
if (table[locate] == NULL)
{
table[locate] = temp_node;
}
else
{
temp_node->next = table[locate];
table[locate] = temp_node -> next;
}
numberofwords++;
}
fclose(temp);
// TODO
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
return numberofwords;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
node *start = table[i];
node *freeer = start;
node *remember = start;
while (remember != NULL)
{
remember = remember->next;
free(freeer);
freeer = remember;
}
}
// TODO
return true;
}
here is the link to errors
https://submit.cs50.io/check50/ef7901d85e821af117b76bf7a2f43f44f38e3301
This looks like a problem in load:
temp_node->next = table[locate];
table[locate] = temp_node -> next;
It looks circular, they are pointing to each other.
Try debugging with the small dictionary and a text file that contains the 5 words in ACTUAL OUTPUT pane plus the word cat.
check50 did not check for memory errors because of the failed test ("can't check until a frown turns upside down")

cs50 speller problem hash table doesn't seem to form in load function

currently doing the speller problem of cs50 pset5.
I'm having a trouble with forming the hash table and i think it causes a segmentation fault later on when i try to run a function that searches the table.
this is the function that creates the hash table:
bool load(const char *dictionary)
{
FILE *dict = fopen(dictionary, "r"); //opens dictionary file
if (dict == NULL) // if cant be opened loading failed
{
return false;
}
char w[LENGTH + 1]; //buffer (length is the maximum character number
int i = 0; //index within word
while(fscanf(dict, "%s", w) != EOF) // scanning the dictionary for words
{
int x = hash(w); //getting the number of the linked list within the table
node *n = malloc(sizeof(node)); //allocating memory for a new node
if (n == NULL)
{
return false;
}
for (int j = 0; j < strlen(w) + 1; j++) // documenting the word within the new node
{
n->word[i] = w[j];
}
n->next = table[x];
table[x] = n; //new node is the beginning of the linked list
dicsize++;
}
fclose(dict);
return true;
}
my main question is whether my code for forming the table is correct and if not then why
thank you in advance
and this is the entire code:
// Implements a dictionary's functionality
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.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 = 26;
int dicsize = 0;
// Hash table
node *table[N];
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
int x = hash(word);
node *cur = table[x];
while(table[x] != NULL)
{
if(strcasecmp(word, cur->word) == 0)
{
return true;
}
if(cur == NULL)
{
return false;
}
cur = cur->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
char temp = tolower(word[0]);
int place = (temp - 97);
return place;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
FILE *dict = fopen(dictionary, "r"); //opens dictionary file
if (dict == NULL) // if cant be opened loading failed
{
return false;
}
char w[LENGTH + 1]; //buffer
int i = 0; //index within word
while(fscanf(dict, "%s", w) != EOF) // scanning the dictionary for words
{
int x = hash(w); //getting the number of the linked list within the table
node *n = malloc(sizeof(node)); //allocating memory for a new node
if (n == NULL)
{
return false;
}
for (int j = 0; j < strlen(w) + 1; j++) // documenting the word within the new node
{
n->word[i] = w[j];
}
n->next = table[x];
table[x] = n; //new node is the beginning of the linked list
dicsize++;
}
fclose(dict);
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
printf("%i", dicsize);
return dicsize;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
return false;
}
The likely culprit is
for (int j = 0; j < strlen(w) + 1; j++) // documenting the word within the new node
{
n->word[i] = w[j];
}
As i is not changing inside the loop, instead of copying the string it will dump all the chars into one. The other index should also be j. (as in n->word[j] = w[j];)
It would be better to do this as strcpy anyway.

Pset5 Speller: I'm getting segmentation fault with small dictionary

When i used check50, my program was not giving any report as output. So i tried my code with small dictionary and i got a segmentation fault. I think it has do with my unload function
This is my code
// Implements a dictionary's functionality
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <ctype.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 = 125;
int word_size = 0;
// Hash table
node *hashtable[N];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
//Convert the word to lowercase
int length = strlen(word);
char copy[length + 1];
for (int i = 0; i < length; i++)
{
copy[i] = tolower(word[i]);
}
copy[length] = '\0';
//Find out the hash value
int hash_value = hash(copy);
node *tmp = hashtable[hash_value];
//Check if word is in dictionary
while(tmp != NULL)
{
if(strcasecmp(tmp->word, copy) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
//It's djb2 hash function
unsigned int hash = 5381;
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)
{
//Initialize all indexs of hastable to NULL
for(int i =0; i < LENGTH + 1; i++)
{
hashtable[i] = NULL;
}
char word[LENGTH +1];
int pos;
FILE *dict = fopen(dictionary,"r");
if(dict == NULL)
{
return false;
}
//Scan every word...I think my problem is in here
while (fscanf(dict, "%s", word) != EOF)
{
word_size++;
int length = strlen(word);
char copy[length + 1];
for (int i = 0; i < length; i++)
{
copy[i] = tolower(word[i]);
}
copy[length] = '\0';
node *new_node = malloc(sizeof(node));
strcpy(new_node->word,copy);
new_node->next = NULL;
//Find the hash value
pos = hash(copy);
//Set the pointer of the new node to index of hashtable
new_node->next = hashtable[pos];
hashtable[pos] = new_node;
}
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return word_size;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
node *cursor = NULL;
node* tmp = NULL;
for(int i=0; i < N; i++)
{
while(cursor->next != NULL)
{
tmp = cursor;
cursor = cursor->next;
free(tmp);
}
free(cursor);
}
return true;
}
Can anyone say the write logic if my unload function is wrong. It works fine with large dictionary. I tried but couldn't figure out how to use debug50
In your unload () function you soon define
node *cursor = NULL;
but then, without assigning to cursor any other value, you dereference it:
while ( cursor->next != NULL )
Dereferencing a NULL pointer raises undefined behavior, and it will likely result in a segmentation fault.
The following action is free(cursor); that, with a NULL pointer, is not good as well.

CS50 Pset5 : code cannot compile because of linker failure

I just finish writing a simple code for Pset5 speller just to check if my code is able to compile. The code is written into the header file. However, when I try to compile the file the error clang-7: error: linker command failed with exit code 1 shows up. Based on my shallow understanding of what have read online, it says that this error would occur if I declare and call a function that does not have any definition. Any help would be much appreciated. Here is my code:
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.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 = 26;
// Hash table
node *table[N];
// Returns true if word is in dictionary else false
//uses the hash table to check
bool check(const char *word)
{
int hashindex = hash(word);
node *tmp = table[hashindex];
while (tmp->next != NULL)
{
if (strcmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
//hashing the first letter of the string
unsigned int value1 = (int) *(word);
unsigned int value2;
if (isupper(value1))
{
value2 = tolower(value1);
}
else
{
value2 = value1;
}
int hashvalue = value2 % 97;
return hashvalue;
}
// Loads dictionary into memory, returning true if successful else false
//hashes the words in the dictionary file
bool load(const char *dictionary)
{
// open dictionary file to load
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
printf("Could not open %s.\n", dictionary);
return false;
}
//making an array that can store scanned words from the dictionary
char dictionaryword[LENGTH];
//initializing all the buckets in the table
for (int i = 0; i < N; i++)
{
table[i] = NULL;
}
//loop to read the word one-by-one
while(fscanf(file, "%s", dictionaryword) != EOF)
{
//creating a new node to store the word
node *n = malloc(sizeof(node));
if (n == NULL)
{
return false;
}
strcpy(n->word, dictionaryword);
n->next = NULL;
//hashing the word to determine which bucket to store it in
int hashindex = hash(n->word);
//checking for any collisions
if (table[hashindex] == NULL)
{
table[hashindex] = n;
}
else
{
//adding new node from the end
node *tmp = table[hashindex];
while (tmp->next != NULL)
{
tmp = tmp->next;
}
tmp->next = n;
}
memset (dictionaryword, 0, LENGTH);
}
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
//the biggest number in the hash table
unsigned int size(void)
{
//iterate over each bucket, assuming all the buckets are filled
unsigned int counter = 0;
for (int i = 0; i < N; i++)
{
node* tmp = table[i];
while(tmp->next != NULL)
{
tmp = tmp->next;
counter++;
}
}
return counter;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
//if the bucket is not filled, memory is leaked somewhere
if (table[i] == NULL)
{
return false;
}
while (table[i] != NULL)
{
node *tmp = table[i]->next;
free(table[i]);
table[i] = tmp;
}
}
return true;
}
EDIT: This is the header file
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include <stdbool.h>
// Maximum length for a word
// (e.g., pneumonoultramicroscopicsilicovolcanoconiosis)
#define LENGTH 45
// Prototypes
bool check(const char *word);
unsigned int hash(const char *word);
bool load(const char *dictionary);
unsigned int size(void);
bool unload(void);
#endif // DICTIONARY_H

Resources