C从文件读取以填充链接列表

时间:2016-11-14 14:38:16

标签: c linked-list scanf

我有一个txt文件,我需要阅读并填充链接列表。文件结构如下

IBE0101;2016;11;20;07;50;Alvaro;Carvajal;12345678R
IBE0101;2016;11;20;07;50;Juan;Garcia;12345678R

我正在尝试阅读以下内容

tPassenger * ops_loadPassengersList()
{
    tPassenger * retValue; 

    retValue = malloc(sizeof(tPassenger));

    tPassenger *lastPassenger = retValue;

    // Open file handle with read mode
    FILE *file = fopen(OPS_PASSENGERS_FILE, "r");

    // Loop until end of file
    while(!feof(file)) {
        tDateTime date;
        fscanf(file, "%[^;];%d;%d;%d;%d;%d;%[^;];%[^;];%[^;]\n", lastPassenger->name, &date.year, &date.month, &date.day, &date.hour, &date.minute, lastPassenger->name, lastPassenger->surname, lastPassenger->dni);
        printf(lastPassenger->name);
        if(!feof(file)) {
            lastPassenger->nextPassenger = malloc(sizeof(tPassenger));
            lastPassenger = lastPassenger->nextPassenger;
        }
    }


    // Close file handle
    fclose(file);

    return retValue;
}

然而,由于fscanf无法找到我告诉扫描的内容,我陷入无限循环?第一次迭代工作正常时,模式似乎是正确的。

这件作品中没有使用tDateTime元素,但我也希望得到它。

2 个答案:

答案 0 :(得分:1)

可能你不应该自己解析这条线。有一个strtok()函数可以为你提供由分隔符分隔的标记。但是,这不会在一次通话中将所有游戏组合在一起。您需要多次调用它,因为字段数在文件的一行中。

讨论了类似方法here

答案 1 :(得分:1)

这样的事情可行:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXCHAR 100

typedef struct {
    int yyyy, mm, dd;
} date_t;

typedef struct {
    int hh, min;
} times_t;

typedef struct node node_t;

struct node {
    char *passenger_num, *name, *lastname, *dni;
    date_t date;
    times_t times;
    node_t *next;
};

typedef struct {
    node_t *head;
    node_t *foot;
} list_t;

list_t *create_list(void);
list_t *insert_nodes(list_t *list, FILE *filename);
void free_list(list_t *list);
void print_list(list_t *list);
void exit_if_null(void *ptr, const char *msg);
void *malloc_str(size_t bytes);

int
main(int argc, char const *argv[]) {
    FILE *filename;
    list_t *list;

    if ((filename = fopen("passengers.txt", "r")) == NULL) {
        fprintf(stderr, "%s\n", "Error reading file!");
        exit(EXIT_FAILURE);
    }

    list = create_list();

    list = insert_nodes(list, filename);

    print_list(list);

    free_list(list);
    list = NULL;

    return 0;
}

list_t
*insert_nodes(list_t *list, FILE *filename) {
    char line[MAXCHAR];
    node_t *newnode;
    char *passenger, *name, *lastname, *dni;
    char *yyyy, *mm, *dd, *hh, *min;

    while (fgets(line, MAXCHAR, filename) != NULL) {
        passenger = strtok(line, ";");
        yyyy = strtok(NULL, ";");
        mm = strtok(NULL, ";");
        dd = strtok(NULL, ";");
        hh = strtok(NULL, ";");
        min = strtok(NULL, ";");
        name = strtok(NULL, ";");
        lastname = strtok(NULL, ";");
        dni = strtok(NULL, "\n");

        newnode = malloc(sizeof(*newnode));
        exit_if_null(newnode, "Node Allocation");

        newnode->date.yyyy = atoi(yyyy);
        newnode->date.mm = atoi(mm);
        newnode->date.dd = atoi(dd);
        newnode->times.hh = atoi(hh);
        newnode->times.min = atoi(min);

        newnode->passenger_num = malloc_str(strlen(passenger));
        strcpy(newnode->passenger_num, passenger);

        newnode->name = malloc_str(strlen(name));
        strcpy(newnode->name, name);

        newnode->lastname = malloc_str(strlen(lastname));
        strcpy(newnode->lastname, lastname);

        newnode->dni = malloc_str(strlen(dni));
        strcpy(newnode->dni, dni);

        newnode->next = NULL;
        if (list->foot == NULL) {
            list->head = newnode;
            list->foot = newnode;
        } else {
            list->foot->next = newnode;
            list->foot = newnode;
        }

    }
    return list;
}

void
*malloc_str(size_t bytes) {
    void *ptr = malloc(bytes+1);
    exit_if_null(ptr, "Initial Allocation");
    return ptr;
}

void
print_list(list_t *list) {
    node_t *curr = list->head;

    printf("Nodes inserted into linked list:\n");
    while(curr) {
        printf("%s;%4d;%2d;%2d;0%d;%2d;%s;%s;%s\n", 
                curr->passenger_num, curr->date.yyyy, 
                curr->date.mm, curr->date.dd, 
                curr->times.hh, curr->times.min, 
                curr->name, curr->lastname, curr->dni);
        curr = curr->next;
    }
}

void
free_list(list_t *list) {
    node_t *curr, *prev;
    curr = list->head;
    while (curr) {
        prev = curr;
        curr = curr->next;
        free(prev);
    }
    free(list);
}


list_t 
*create_list(void) {
    list_t *list = malloc(sizeof(*list));
    exit_if_null(list, "Initial Allocation");
    list->head = NULL;
    list->foot = NULL;
    return list;
}

void
exit_if_null(void *ptr, const char *msg) {
    if (!ptr) {
        printf("Unexpected null pointer: %s\n", msg);
        exit(EXIT_FAILURE);
    }
}