0

I think I'm close, but I'm running into a Segmentation Fault when I run the code below. It was running before and spitting back out all the words, not just misspelled ones, but now I can't even get that.

Thanks in advance for any guidance.

Header files, trie struct and check function:

#include <stdbool.h>

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

#include <ctype.h>

#include "dictionary.h"

unsigned int num_words = 0;

// Build Trie struct
typedef struct node
{
    bool is_word;
    struct node* children[27]; 
}
node;
node* root;

/**
 * Returns true if word is in dictionary else false.
 */
bool check(const char* word)
{
    node* cursor = root;
    int letter;
    // Travel downwards in trie

    /** 
     * For each letter in input word
     * go to corresponding element in children
     */
    for (int index = 0; index < strlen(word); index++)
    {
        if (isalpha(word[index]))
        {
            letter = tolower(word[index]) - 'a';
        }

        else if(word[index] == '\'')
        {
            letter = 26;
        }

        // if letter not found at that position in trie, return false
        if(cursor -> children[letter] == NULL)
        {
            return false;
        }

         //if the letter is found, move to next letter
         else
         cursor = cursor -> children[letter];
        }
    //once at end of input word, check if is_word is true return true or     false
    if (cursor -> is_word == true)
    {
        return true;
    }
    return false;
}

Load function:

//** * Loads dictionary into memory. Returns true if successful else false. / bool load(const char dictionary) { root = malloc(sizeof(node)); node* cursor = root;

    // Open dictionary file for reading and ensure it can be opened
    FILE* dict = fopen(dictionary, "r");
    if (dict == NULL)
    {
        printf("Could not open dictionary.\n");
        return 1;
    }

    // Go through every character in every word in the dictionary
    for (int c = fgetc(dict); c != EOF; c = fgetc(dict))
    {
        // hard code value for '\''
        if (c == '\'')
        {
            c = 'z' + 1;
        }

        /** 
         * Get a numeric value for every character, change it lowercase,
         * and use its ascii value to calculate an index for the children 
         * array, which starts at zero.
         */
        int index = tolower(c) - 'a';

        // if node does not exist
        if(cursor -> children[index] == NULL)
        {
            // malloc a new node and have children[index] point to it
            node* new_node = malloc(sizeof(node));
            cursor -> children[index] = new_node;
        } 
        // if not NULL move to a new node and continue
        cursor = cursor -> children[index];

        //if at end of word, set is_word to true and increment num_words by 1;

        if(c == '\n')
        {
            cursor -> is_word = true;
            num_words++;
            *cursor = *root;
        }
    }    
   // close file
    fclose(dict);
    return true;
}
0

1 Answer 1

1

letter = 28; should be letter = 26;

Maybe you should use calloc instead of malloc (calloc zeroes the memory chunk, setting all the pointers to NULL and the boolean to false)

Also, lines in text files are separated by \n (UNIX style, MS-DOS uses \r\n, old Mac OS \r), not \0, and should additionally reset cursor to root

1
  • Thanks @Blauelf! That was a really silly error setting letter to 26. I'm not sure how to go about reset cursor to root. When I use cursor = root; I get a segmentation fault. And when I use *cursor = *root; I continue to get all my words back out of the speller.c function not just the misspelled ones. Updating the above code accordingly.
    – MKD
    Commented Nov 2, 2016 at 18:11

You must log in to answer this question.

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