1

I'm completely stuck here. Running pset5 code and got a strange problem, code is not working as it should in large dictionaries, only in small ones.

I think problem may be in load. I'm attaching load and check codes:

Thanks a lot!!!!

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



/**
 * Returns true if word is in dictionary else false.
 */

typedef struct node
    {
        bool is_word;
        struct node* children[27];
    }
    node;

node* root;
int words2 = 0;    
bool aux2 = false;
int freeing(node* trav, int words2);

bool check(const char* word)
{
    int c;
    int aux = 2;
    node* trav = root;
    int length = strlen(word);

        for(int i = 0; i < length; i++)
        {
            aux = 2;
            if(tolower(word[i]) >= 'a' && tolower(word[i]) <= 'z')
            {
                c = tolower(word[i]) - 'a';

            }
            else
            {
                c = word[i] - 13;
            }

            if(trav->children[c] == NULL)
            {
                return false; 
                   aux = 0;
            }
            else
            {
                trav = trav->children[c];
            }
        }
        if(trav->is_word == true)
            {
                //printf("CHECK:%p \n",trav);
                return true;
                aux = 1;
            }

    if(aux == 1)
    {
        return true;
    }
    else
    {
        return false;
    }

}


bool load(const char* dictionary)
{
    root = malloc(sizeof(node));

    int index = 0;
    root->is_word = false;
    node* trav = root;
    node* new_node;

    FILE* fp = fopen(dictionary, "r");
    if(fp == NULL)
    {
        return false;
    }

    while(fgetc(fp) != EOF)
    {
        fseek(fp, -1, SEEK_CUR);
        for(int c = fgetc(fp); c != '\n'; c = fgetc(fp))
        {
            if(c >= 'a' && c <= 'z')
            {
                index = c - 'a';
            }
            else
            {
                index = c - 13;
            }

            if(trav->children[index] == NULL)
            {
                if(fgetc(fp) == '\n')
                {
                    //fseek(fp,-1,SEEK_CUR);
                    //printf("%c",fgetc(fp));
                    new_node = malloc(sizeof(node));
                    for(int i = 0; i < 27; i++)
                    {
                    new_node->children[i] = NULL;
                    }

                    new_node->is_word = true;
                    trav->children[index] = new_node;
                    words2++;
                    //ver direccion
                    //printf("LOAD true : %i , %p ",index,new_node);
                    break;
                }
                else
                {
                    new_node = malloc(sizeof(node));
                    for(int i = 0; i < 27; i++)
                    {
                        new_node->children[i] = NULL;
                    }
                    trav->is_word = false;
                    new_node->is_word = false;
                    //printf("LOAD false : %i , %p ",index,trav);
                    fseek(fp, -1, SEEK_CUR);
                    trav->children[index] = new_node;

                    trav = trav->children[index];
                }
            }
            else
            {
               trav = trav->children[index];
            }
        }
        //trav->is_word = true;
        trav = root;
    }
    fclose(fp);
    return true;
}
0

I copy and pasted your load function in a brand new pset5 and it compiled fine. I could not see any obvious mistakes on the code so I went ahead and debugged it with gdb.

I did see a behavior that might be causing problems.

I am going to number the lines based on the piece of code you gave.

#include <stdbool.h> // line #1

if(tolower(word[i]) >= 'a' && tolower(word[i]) <= 'z') // line #36

As you load the words you set all the is_word to false. I did the same when I first did this pset. But I can tell you that you don't need to set to false any booleans nor to NULL any pointers. When you malloc a node, all the pointers inside the array will be NULL and all the booleans will be false.

The problem with line 130:

trav->is_word = false;

Is that you are setting the is_word to true one node after the last one.

For example:

          root -> c    -> a    -> t     -> end node
is_word = false   false   false   false    true

So when you do caterpillar and you get to the e, the next node pointer that you need is NULL, the letter is not a \n and therefore line 130 executes and overwrites the true that you had in that boolean.

I suggest you delete lines 111-114, 126-129, 130 and 131.

111-114 and 126-129 are the same:

for(int i = 0; i < 27; i++)
{
    new_node->children[i] = NULL;
}

130:

trav->is_word = false;

131:

new_node->is_word = false;

That way if you have a word that fits inside another word, you don't set to false what you previously set to true. For example:

cat
caterpillar
2
  • Thanks a lot! To be brief only that one line of code was causing the overwriting problem, I figured that out as soon as you pointed that line out to me. Code's running smooth now, thanks again! – Jose Hernández S.C. Oct 21 '16 at 23:12
  • Thanks to you. You are coding great work there! – Ricardo David Antonetti Oct 22 '16 at 8:48

You must log in to answer this question.

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