Search code examples
clinked-listfgets

Linked list from a file of words


I'm struggling with a C issue and I can't figure what I'm doing wrong.

I'm using a linked list to store words. When I execute the following:

list *myList = list_new();
list_append(myList,"Word_01");
list_append(myList,"Word_02");
list_append(myList,"Word_03");
list_append(myList,"Word_04");
list_print(myList);

Everything is OK and I get this output:

Word_01 -> Word_02 -> Word_03 -> Word_04 -> NULL

OK, now I take the words from a list stored in a file:

Word_01
Word_02
Word_03
Word_04

And execute this code:

const char *filename;
filename = "list";
list *myList2 = list_new();
FILE* file = NULL;
size_t size;
char line[256];
file = fopen(filename, "r");
if (file != NULL)
{
    printf("File opened.\n");
    while (fgets(line, 256, file) != NULL) {
        list_append(myList2, line);
    }
    fclose(file);
}
else {
    printf("Could not open file.\n");
    exit(EXIT_FAILURE);
}
list_print(myList2);

Then I get the following output:

Word_04 -> Word_04 -> Word_04 -> Word_04 -> NULL

Can someone explain me why is this happening?

Edit: Here is list_append()

void list_append(list *l, char *w) {
    word *new_word = malloc(sizeof(word));
    if (l == NULL || new_word == NULL) {
        exit(EXIT_FAILURE);
    }
    new_word->_word = w;
    new_word->next = NULL;
    if (l->first->_word == "") {
        l->first = new_word;
    }
    else {
        word *temp = malloc(sizeof(word));
        temp = l->first;
        while(temp->next != NULL) {
            temp=temp->next;
        }
        temp->next = new_word;
    }
}

Solution

  • As the comments noted, you're handling the character strings incorrectly. C-style strings are not things that you can equate with ==, or assign with =. This is a C++ tutorial, but gives a good explanation of C-strings:

    http://www.learncpp.com/cpp-tutorial/66-c-style-strings/

    Also check out the documentation for strcmp(), strcpy() and strlen(). I fixed the bits noted in the comments using those functions - note my comments:

    void list_append(list *l, char *w) {
        word *new_word = malloc(sizeof(word));
        if (l == NULL || new_word == NULL) {
            exit(EXIT_FAILURE);
        }
    
        //new_word->_word = w;
        // Allocate space and copy contents, not the pointer
        new_word->_word = malloc(strlen(w) + 1);
        strcpy(new_word->_word, w);
    
        new_word->next = NULL;
        //if (l->first->_word == "") {
        // Use strcmp() to compare the strings - returns 0 if they are equal
        if (strcmp(l->first->_word, "") == 0) {
            l->first = new_word;
        }
        else {
            word *temp = malloc(sizeof(word));
            temp = l->first;
            while(temp->next != NULL) {
                temp=temp->next;
            }
        temp->next = new_word;
        }
    }