1

I am really close here.

This reads the file in and using gdb I can see the words from my text file going to the linked list.

However when I print my linked list (bottom part of code) the whole linked list seems to just contain the last word from the file duplicated for however many entries are in the file.

bool load(const char* dictionary) {
    // open dictionary
    FILE* file = fopen(dictionary, "r");
    if (file == NULL)
        return false;

    char buf[LENGTH];

    //read the contents of the file and write to linked list
    while (!feof(file)) {
        fscanf(file,"%s", buf);

        // try to instantiate node
        node* newptr = malloc(sizeof(node));
        if (newptr == NULL) {
            return false;
        }

        // initialize node
        newptr->next = NULL;

        // add new word to linked list
        newptr->dictword = buf;

        //move node to start of linked list
        newptr->next = first;
        first = newptr;
    }

    fclose(file); 

    // traverse and print list.
    node* ptr = first;
    while (ptr != NULL) {
        printf("%s\n", ptr->dictword);
        ptr = ptr->next;
    }

    return true;
}
Stephen Docy
  • 4,738
  • 7
  • 18
  • 31
Dan Heaford
  • 451
  • 3
  • 11

4 Answers4

1

You only have one char buf[] into which you read every word. You save a pointer to that buffer in every linked list element, but you immediately read over the data. You need to copy it when you put it into the allocated node. The easiest way is to use newptr->dictword = strdup(buf) which does the alloc and copy in one step.

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
0

Assuming dictword is of size LENGTH just as your buf, i.e:

struct node {
...
...
    char dictword[LENGTH];
...
...
};

you need to make the following changes in your code:

strcpy(newptr->dictword, buf);

The problem was that you were just setting the dictword to point to the same memory as buf in all the nodes of the linked list.

A better approach would be to dynamically allocate the memory for the string:

struct node {
...
...
    char* dictword;
...
...
};

newptr->dictword = (char*)malloc(strlen(buf) + 1);
strcpy(newptr->dictword, buf);
Tuxdude
  • 47,485
  • 15
  • 109
  • 110
0

I recommend strdup solution as BenJackson's. But it does not exist in the standard C library.

Here is my workaround for it:

char *strdup(const char *data)
{
   char *retval = malloc(strlen(data) + 1);
   strcpy(retval, data);
   return retval;
}
Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
0

There is a problem with the line:

// add new word to linked list
newptr->dictword = buf;

In this way you are allways passing the reference to the beginning of the buf to all your elements, so as you update the "buf" all elements are updated. And that's why you have the referred behaviour.

Try replace it by:

newptr->dictword = (char*) malloc((strlen(buf)+1)*sizeof(char));
strcpy(newptr->dictword, buf);

The "strlen(buf)+1" is the length of the current string stored in buf plus the space for the character "\0", which means end of string.

PS. assuming you have declared the elements "dictword" with char*.

sissi_luaty
  • 2,839
  • 21
  • 28