0

enter image description hereMy code finally works, and I believe it is operating correctly but check50 says otherwise. Anyone see any blatant issues in my code that you can point out?

// Implements a dictionary's functionality

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "dictionary.h"
// Represents number of children for each node in a trie
#define N 27

// Represents a node in a trie
typedef struct node
{
    bool is_word;
    struct node *letters[N];
}
node;
// Represents a trie//topmost node
node *root = NULL;


//to keep track of number of words in the dictionary
int dictionNum = 0;

//prototypes
int index_char(char c);
node *getnode(void);
node *root;

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    node *t = root;
    int index;
// to check each letter in the input word
    for(int i = 0, n = strlen(word); i < n; i++){

        index = index_char(word[i]);
        if(!t->letters[index]){
            return false;
        }

        t = t ->letters[index];
    }
    return t->is_word;
}


// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Open dictionary
    FILE *file_ptr = fopen(dictionary, "r");
    if (file_ptr == NULL)
    {
        fprintf(stderr, "File does not exist\n");
        unload();
        return false;
    }

    // Initialize trie
    //root = malloc(sizeof(node));//if NULL, malloc a new node
    // need a node that will traverse through the trie
    root = getnode();
    node *t = root;

    // an array to story the word from the dictionary
    char word[LENGTH];

    // Insert words into trie
    while (fscanf(file_ptr, "%s", word) != EOF)
    {
        int index;
        //iterate over the letters of the word in order to create an index
        for(int i = 0, n = strlen(word); i<n ; i++){

            if(word[i] == '\n'){
                //at the end of the line you have hit the end of a word
                //have to round it out so it can go back to the root
                t ->is_word = true;
                t = root;
                dictionNum ++; //increment for every word in the dictionary
                continue;
            }
            index = index_char(word[i]);

            if(!t->letters[index]){
                t->letters[index]=getnode();
            }

            t = t ->letters[index];
        }
    }

    // Close dictionary
    fclose(file_ptr);

    // Indicate success
    return true;
}

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


// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{

    node *ptr = root;
    while(!ptr){
        //temporary Node to store the header of the list
        node *next = ptr;
        free(ptr);
        ptr = next;
    }
    return true;
}

node *getnode(void){
    root = NULL;
    root = malloc(sizeof(node));
    if(root){
        root->is_word = false;

        for(int i = 0; i < N; i++){
            root->letters[i]=NULL;
        }
    }
    return root;
}

int index_char(char c){

    if(c == '\0'){
        return 26;
    }
    else if(c >= 'A' && c<='Z'){
        return c-65;
    }
    else{
        return c-97;
    }
}
  • What did check50 say? Can you post a link to the results page? – Cliff B Aug 26 '19 at 22:15
  • Just posted a screenshot . – andrewk Aug 26 '19 at 22:28
  • Thanks, but I thought we were working on speller here, not Caesar???? – Cliff B Aug 26 '19 at 22:32
  • woops wrong screenshot. I'll post it rn – andrewk Aug 26 '19 at 22:33
  • 1
    "I believe it is operating correctly". Have you tested it with the sample texts and keys that you were given? And your program marks the same words as misspelled? with the same counts etc? If not, there is no point in running check50. – curiouskiwi Aug 27 '19 at 0:16
0

You stated that the code is working, but I disagree. While it compiles and runs, it isn't working at all. In fact, it is marking every word as misspelled. Is this the correct code or an earlier version? Assuming it's your current version, let's look at it.

Let's look at getnode:

node *getnode(void){
    root = NULL;
    root = malloc(sizeof(node));
    if(root){
        root->is_word = false;

        for(int i = 0; i < N; i++){
            root->letters[i]=NULL;
        }
    }
    return root;
}

Every time getnode() is called (it's called for every letter in the dictionary), the global variable root is nulled and a new node allocated. The result of this is that the starting point of the trie is lost every time a node is created, so all previous work on the trie is lost.

A rework of getnode is in order. There may be more issues, but this is the biggest problem I see.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

| improve this answer | |
  • I'm not going to lie this allocation of memory is the most complicated thing I've come across in programming. Can you be a little more specific. – andrewk Aug 26 '19 at 22:55
  • Yeah, DON'T use the global variable root inside of getnode(). Use a local var name, like mabe newnode. Remember, a global variable can be accessed from anywhere in the program. Local variables are scope restricted to where they are created. – Cliff B Aug 26 '19 at 23:05
  • I used a local variable instead of root and it did the same thing, everything was considered misspelled. – andrewk Aug 26 '19 at 23:26
  • My recommendation is to run it through debug50 using a small dictionary as both dictionary and test file and see what's happening. After working on that, if you still can't fix it, post the new code in a new question. – Cliff B Aug 26 '19 at 23:41

You must log in to answer this question.

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