0

I hope i don't get voted down to quickly for this, but I have a project I'm working on for school in which I have to build a spell checker. I decided to use a trie, and it seems to be working, but I have a bug I can't find. I think the issue is in the following,

bool load(const char* dictionary)
{

    if (!rootNode)
    {
        rootNode = trieNodeCreate();
        if (!rootNode)
        {
            printf("could not allocate root node");
            return false;
        }
    }

    // Open the file 
    FILE* fp = fopen(dictionary, "r");

    if (fp == NULL)
    {
        printf("could not open dictioanry %s\n", dictionary);
        return false;
    }


    int index = 0;
    for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
    {
        char word[LENGTH];
        if (c != '\n' )
        {
            word[index] = c;
            index++;
        }
        else
        {
            trieWordInsert(word, rootNode);
            index = 0;
                wordCount ++;

        } 

    }
    fclose(fp);

    if (wordCount)
    {
        return true;
    }
    return false;
}

but I've been unable to find it. The rest of the project can be found at

https://github.com/iMillJoe/spell-checker

Joe Million
  • 147
  • 9

2 Answers2

2

Declare your word[LENGTH] array outside of the loop, else it will just discard the word pointer and free the allocated at the end of each cycle, create a new one. I don't think you want that, I think you would rather want that only when the if condition does not get fulfilled.

I may not know what trieWordInsert does, but I will assume that you'll need a 0 terminator.

  • Declare word[LENGTH] = { 0 }; right before the for( ... ) { ... }
  • Add a memset( word, 0, LENGTH); inside the else block there
  • Include memory.h or string.h for the memset if you haven't included either one of those by far

And this should be it, I think...

Edit: After having learned how trieWordInsert more or less issues the word pushed in...

DIRECT CODE FOR EZ MODE:

bool load( const char* dictionary )
{

    if ( !rootNode )
    {
        rootNode = trieNodeCreate( );
        if ( !rootNode )
        {
            printf( "could not allocate root node" );
            return false;
        }
    }

    // Open the file 
    FILE* fp = fopen( dictionary, "r" );

    if ( fp == NULL )
    {
        printf( "could not open dictioanry %s\n", dictionary );
        return false;
    }

    int index = 0;
    char word[LENGTH];
    for ( int c = fgetc( fp ); c != EOF; c = fgetc( fp ) )
    {
        if ( c != '\n' )
        {
            word[index] = c;
            index++;
        }
        else
        {
            word[index] = 0;
            trieWordInsert( word, rootNode );
            index = 0;
            wordCount++;
        }

    }
    fclose( fp );

    if ( wordCount )
    {
        return true;
    }
    return false;
}
Utkan Gezer
  • 3,009
  • 2
  • 16
  • 29
  • The `memset` is a tad overkill; just make sure the string is terminated before sending it (which should also be protected against adding empty strings, but the OP is likely parsing "correct" data "correctly" so may not be a big deal. None the less, this answer is solid, and up ticked. – WhozCraig Mar 09 '14 at 18:46
  • @WhozCraig who knows... maybe he does something weird inside that `trieWordInsert`, requiring each character pointed by the `word` for `LENGTH` long to be zero. I have only wanted to make sure. – Utkan Gezer Mar 09 '14 at 19:39
1

I think you didn't end the word with a '\0'

char word[LENGTH];
 if (c != '\n' )
 {
     word[index] = c;
     index++;
 }
 else
 {
     word[index] = '\0'; //missing this one!!!
     trieWordInsert(word, rootNode);
     index = 0;
     wordCount ++;
 } 

I think you better use fscanf and read the file word by word.

SHR
  • 7,940
  • 9
  • 38
  • 57
  • Use of fscanf() was warned against in the projects specs. – Joe Million Mar 09 '14 at 18:49
  • Any string must have a terminating null. try to print the words before you call `trieWordInsert` and compare with the file. – SHR Mar 09 '14 at 18:51
  • @Joe - How does `trieWordInsert` know how long the word is that is being inserted? Surely all words are not exactly `LENGTH` long. – M.M Mar 09 '14 at 18:58
  • @MattMcNabb you might be onto something, trieWordInsert calls strlen() to figure out how long the string is. (LENGTH is 45, the longest word in english) If '/0' is not the end of the string, strlen() won't work. – Joe Million Mar 09 '14 at 19:03