【问题标题】:C Read from file to populate linked listC 从文件中读取以填充链表
【发布时间】:2016-11-14 14:38:15
【问题描述】:

我有一个 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 元素没有用在这件作品上,但我也想得到它。

【问题讨论】:

  • 您没有检查fopen()fscanf()malloc() 的返回值吗?你正在阅读lastPassenger->name 两次。
  • 好吧,我只是删除了一些行以使其清楚。是的,问题出在 fscanf 上,因为它在第一次迭代时返回 9(好),但在其余部分返回 0
  • 与许多其他转换说明符相反,[] 不跳过空格。您可能无法匹配在 Windows 上处理数据文件时引入的第一行回车 (\r)...?
  • 所以添加 \n 不会告诉 fscanf 跳到新行吗?那我该怎么解决呢?我在赢是的。
  • (这就是为什么您应该使用fgets() 阅读整行并在内存中进行解析。众所周知,*scanf() 在输入和格式字符串不正确的情况下无法为您提供适当的反馈'不同意。)

标签: c linked-list scanf


【解决方案1】:

您可能不应该自己解析该行。有一个 strtok() 函数可以为您提供由分隔符分隔的标记。但这不会让您一次获得所有领域。您需要调用它的次数与文件一行中的字段数一样多。

类似方法讨论here

【讨论】:

    【解决方案2】:

    这样的事情可能会奏效:

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

    【讨论】:

      猜你喜欢
      • 2013-09-16
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      • 2018-06-30
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 2012-02-20
      相关资源
      最近更新 更多