简体   繁体   English

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

[英]C Read from file to populate linked list

I have a txt file that I need to read and populate a linked list. 我有一个txt文件,需要阅读并填充链接列表。 The file structure is the following 文件结构如下

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

I am trying to read it doing the following 我正在尝试阅读以下内容

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;
}

However I get stuck on a infinite loop by fscanf not finding what I told to scan on? 但是我被fscanf困在了一个无限循环中,没有找到要告诉我进行扫描的内容? The pattern seems correct the first iteration works fine. 模式似乎正确,第一次迭代可以正常工作。

The tDateTime element is not used on this piece but I want to get it too. tDateTime元素未在此片段上使用,但我也想获取它。

Probably you should not parse the line yourself. 可能您不应该自己解析该行。 There is a strtok() function which can give you the tokens separated by a delimiter. 有一个strtok()函数,可以为您提供由定界符分隔的标记。 But this will not give you all the feilds together in one call. 但是,这并不能一call而就。 You will need to call it as many times as the number of fields are in a line of the file. 您将需要多次调用它,只要文件行中的字段数即可。

Similar method is discussed here 这里讨论类似的方法

Something like this could work: 这样的事情可能会起作用:

#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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM