Search code examples
clinked-listfgetsstrtok

Reading file and save information in a liked list using fgets and strtok in C


I'm trying to read a file which has only one line with names separated by commas, so i'm using fgets to read the line and then separate the names with strtok, then i wanted to save those names in a linked list. I'm using CodeBlocks and when i run the program it shows this message: "Process terminated with status -1073741510"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_CHAR 200

typedef struct Names{
    char* name;
    struct Names* next;
}Names;

Names* create_list(){

    Names* aux = (Names*) malloc (sizeof(Names));
    assert(aux);
    aux->next = NULL;
    return aux;
}
void insert_name (Names* n, char* p){

    Names* aux = (Names*)malloc(sizeof(Names));
    aux->name = p;
    while(n->next!=NULL){
        n=n->next;
    }
    aux->next=n->next;
    n->next=aux;
}

void config(Names*p){

    FILE* fp = fopen( "names.txt", "r");

    if(fp == NULL){
        printf("Error opening file");
        return;
    }
    else{
        char line[MAX_CHAR],*token;

        fgets(line, MAX_CHAR, fp);
        token = strtok(line,",");
        insert_name(p,token);
        while(token != NULL);{
            token = strtok(NULL,",");
            insert_name(p,token);
        }
        fclose(fp);
    }
}

void print_list(Names* n){
    Names* l = n->next;
    while (l){
        printf("%s\n",l->name);
        l = l -> next;
    }
}

int main()
{
    Names* n;
    n = create_list();
    config(n);
    print_list(n);

    return 0;
}

Solution

  • You've got an infinite loop here:

    while(token != NULL);{
    

    The semicolon terminates the "body" of the while and the curly brace just opens a code block that isn't attached to any control structure. (That's legal and was a way to scope variables before C99.)

    Without the semicolon, the loop is still wrong: You should only insert when you know that the token isn't NULL:

    token = strtok(line,",");
    
    while (token != NULL) {
        insert_name(p,token);
        token = strtok(NULL,",");
    }
    

    There are still errors in your code:

    • Your tokens are pointers into the local array ´line. When you leaveconfig, these pointers become invalid, becauseline` will become invalid. You should copy the strings instead just storing a pointer.
    • At the end of the program, you should call free for every call to malloc. In other eords, clean up your list.