0

I am totally stumped by the following problem. My code for dictionary.c compiles with 'make' without a problem. However, when I run check50 it fails the compile test with the error at this sandbox url:

https://sandbox.cs50.net/checks/7e7cc38362ea4a3e9f329d3fa6e0998a

There is clearly an issue with my index value, but I cant work out what is it is. The purpose of the index variable is to assign each character to the right node pointer in the array. In previous psets, when iterating through an array Ive always declared an int like 'int i' in a for loop statement and then used the code 'array[i]' in the body of the loop to reference a specific element. Does anyone know why this is an issue with the array of node pointers?

I have now successfully debugged my program so that when I run it against the staff solution for all the diffeerent txt I get a perfect match of misspelled words, however, it still fails the check50 compile test. Can someone please explain to me the error messages detailed at the above url?

Here is my code for the check, load, and size functions (I haven't got to unload yet):

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

// declare trie node data structure
typedef struct node
{
    bool is_word;
    struct node *children[27];
}
node;

// function declaration returning pointer to new node whose node pointers 
are initialized to NULL
node* get_node();

// declare global variable representing sizeof node to minimise running time 
of program  
int nodesize = sizeof(node);

// declare global variables
FILE *dictptr = NULL;
node *root = NULL;
int index;
int chr;
unsigned int wordcount = 0;


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

for (int i = 0; i < length; i++)
{
    if (isalpha(word[i]))
    {
        index = (tolower(word[i])) - 'a';

        if (trav->children[index] == NULL)
        {
            return false;
        }
        if (trav->children[index] != NULL)
        {
            trav = trav->children[index];        
        }
    }
    if (word[i] == '\'')
    {
        if (trav->children[26] == NULL)
        {
            return false;
        }
        if (trav->children[26] != NULL)
        {
            trav = trav->children[26];        
        }
    }
    if (word[i+1] == '\0')
    {
        if (trav->is_word == true)
        {
            return true;
        }
    }

}
return true;
}


bool load(const char *dictionary)
{
dictptr = fopen(dictionary, "r");
if (dictptr == NULL)
{
    return false;
}

// intitialise root node and traversal node
root = get_node();

if (root == NULL)
{
    return false;
}

node *trav = root;

// iterate through every characrter in dictionary
for (int chr = fgetc(dictptr); chr != EOF; chr = fgetc(dictptr))
{
    if (isalpha(chr))
    {   // assign each letter to correct node pointer in array, whether 
upper/lower case
        index = ((tolower(chr)) - 'a');

        // if this elements node pointer is NULL, create new node and have 
pointer point to it 
        if (trav->children[index] == NULL)
        {
            trav->children[index] = get_node();

            if (trav->children[index] == NULL)
            {
                return false;
            }

            trav = trav->children[index];
        }
        // if pointer != NULL set trav pointer to be equal to this element 
 in array
        // thus iterating through the trie    
        else if (trav->children[index] != NULL)
        {
            trav = trav->children[index];
        }
    }
    // handle apostrophe's in the same way as a character
    if (chr == '\'')
    {
        if (trav->children[26] == NULL)
        {
            trav->children[26] = get_node();

            if (trav->children[26] == NULL)
            {
                return false;
            }

            trav = trav->children[26];
        }
        else if (trav->children[26] != NULL)
        {
            trav = trav->children[26];
        }
    }
    if (chr == '\n')
    {
        // set is_word boolean to true to indicate the completion of a word
        trav->is_word = true;
        // increment wordcount value
        wordcount++; 

        // reset trav pointer to point at root node
        trav = root;
    }
}
fclose(dictptr);
return true;
}


unsigned int size(void)
{
    if (&load == 0)
    {
        return 0; 
    }
    else
    {
        return wordcount;
    }

}
node* get_node()
{
    node* newnode = calloc(1, nodesize);

    return newnode;
}
2

On some versions of C, you cannot declare a global variable index if you include <string.h>. Apparently the check50 server has such a version (and the IDE does not). There is a comment about it in the answer to this post.

As an aside, some C implementations (BSD-based) define an index function in string.h which may also cause a problem. Use of this function is deprecated and it doesn't appear in the C standard (use strchr instead) but it may be the cause of problems if you're running on (for example) Mac OS or OpenBSD (or even Linux under some combination of #define settings, I believe).

I found a few other references to this problem; I'll search a while longer to see if I can find something more definitive. Suggest you change the name of the variable. If you view /usr/include/string.h you'll see there is still a definition for a function named index.

For grins, I sent my vigenere through check50 (it includes string.h), and it passed all tests. I modified it and added a global variable named index, and check50 failed, with a similar error (which references string.h specifically):

... but received the following on standard error instead —

vigenere.c:7:5: error: redefinition of 'index' as different kind of symbol
int index;
    ^
/usr/include/string.h:485:14: note: previous definition is here
extern char *index (const char *__s, int __c)

Suspect the different result when compiling speller is because dictionary.c does not have a main function.

| improve this answer | |
  • Thanks so much, @DinoCoderSaurus, after changing the variable name my program now passes the check50 compile test! Really appreciate your research and advice, I had no idea how to deal with the problem. – adam kirsch Jun 27 '17 at 15:34

You must log in to answer this question.

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