0

Why does the code in the wile loop inside the load function only get executed once?

/**
 * Implements a dictionary's functionality.
 */

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

#include "dictionary.h"

// root of the dictionary trie
node* root = NULL;

int count = 0;

/**
 * Returns true if word is in dictionary else false.
 */
bool check(const char *word)
{
    node* nodeptr = root;
    for (int i = 0, n = strlen(word); i < n; i++)
    {
        if (nodeptr->children[hash(word[i])] == NULL)
        {
            return false;
        }
        nodeptr = nodeptr->children[hash(word[i])];
    }
    return nodeptr->is_word;
}

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

    // set all pointers in root to NULL
    for (int j = 0; j < 27; j++)
    {
        root->children[j] = NULL;
    }

    // open dictionary
    FILE* file = fopen(dictionary, "r"); 
    char word[LENGTH + 1];

    node* current;
    current = root;

    // iterates over words in dictionary
    while (fscanf(file, "%s", word) != EOF)
    {
        count++;
        // do something times while n is the length of the word
        for (int i = 0, n = strlen(word); i < n; i++)
        {
            // check if the loop i is equal the last character of the word
            if (i == n - 1)
            {
                //  check if there exists a node pointer on the path of the word
                if (current->children[hash(word[i])] == NULL)
                {
                    // crate a new node
                    node* new_node = malloc(sizeof(node));
                    new_node->is_word = false;
                    for (int j = 0; j < 27; j++)
                    {
                        new_node->children[j] = NULL;
                    }

                    // check is node is successfully created
                    if (new_node == NULL)
                    {
                        unload();
                        return false;
                    }

                    current->children[hash(word[i])] = new_node;
                    new_node->is_word = true;
                }
                else
                {
                    current->children[hash(word[i])]->is_word = true;
                }
            } 
            else if (current->children[hash(word[i])] == NULL)
            {
                // crate a new node
                node* new_node = malloc(sizeof(node));
                new_node->is_word = false;
                for (int j = 0; j < 27; j++)
                {
                    new_node->children[j] = NULL;
                }

                // check is node is successfully created
                    if (new_node == NULL)
                    {
                        unload();
                        return false;
                    }

                current->children[hash(word[i])] = new_node;
                current = new_node;
            }
            else
            {
                current = current->children[hash(word[i])];
            }
        }

        // Close the open file
        fclose(file);

        return true;
    }

    // Close the open file
    fclose(file);

    unload();

    return false;
}

// returns a hash number
int hash(char character)
{
    if (isalpha(character))
        return tolower(character) - 97;
    else
        return 26;
}

/**
 * Returns number of words in dictionary if loaded else 0 if not yet loaded.
 */
unsigned int size(void)
{
    return count;
}

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

bool node_free(node* ptr)
{
    for (int i = 0; i < 27; i++)
    {
        if (ptr->children[i] != NULL)
        {
            node_free(ptr->children[i]);
        }
    }
    free(ptr);
    return true;
}
0

Your logic in the load function looks good to me, at least without having tested it, but did I miss it, or did you ever create the struct for your trie? You should probably create the struct globally at the very beginning of dictionary.c (after the #includes) because you will be referencing to it in almost every function. In the walkthrough Zamyla shows you one possible way to create this struct. There may be other problems, but this one seems to be the root of yours.

2
  • This cant be the problem because if the compiler wouldntfind the definition of the node struct I would get an error. And if I write the struct in the dictionary.c file I get an error because I use the node struct in the function declaration in the dictionary.h file. And I can`t write the struct in both files without getting an errror. Jul 5 '17 at 14:45
  • Hmm you may be right, but you might want to try to copy your struct to where into dictionary.c right after #includes and delete it from dictionary.h just to make sure that isn't the problem. Sometimes even if the compiler finds no problems, it still creates issues. However I don't know much about this myself, so if you want you can ask your question again in a new thread so it gets more attention perhaps? Jul 5 '17 at 18:31

You must log in to answer this question.

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