首页 > 解决方案 > C从txt文件中读取并存储在链表中

问题描述

我的目标是逐行读取文本文件,然后将每一行分成不同的变量。我尝试使用 fgets 并成功将其存储到链表中。但是它存储了整行,相反,我只想将它存储到分号。例如,第一行是:

1;IMG_3249.JPG;730x1114;158KB;Hamburg;Germany;16/03/2020 09:12

在这里,我希望将“1”存储在 id 中,“IMG_3249”存储在名称中。它是这样的。到目前为止,我做到了这一点;

struct list {
    char *string;
    int id;
    char *name;
    char *dim;
    char *size;
    char *location;
    char *date;
    struct list *next;
};
typedef struct list LIST;


int main ()
{
     FILE *fp;
     char line[110];
     LIST *current, *head;

     head = current = NULL;
     fp = fopen("PhotoInfoBook.txt", "r");

     while(fgets(line, sizeof(line), fp)){
        LIST *node = malloc(sizeof(LIST));
        node->string = strdup(line);
        node->next =NULL;

        if(head == NULL){
            current = head = node;
        } else {
            current = current->next = node;
    }
    }
    fclose(fp);
}

关于我应该如何进行的任何想法?

标签: clinked-list

解决方案


有几个函数可以使 C 中的这种处理更容易、更安全。请阅读 getline、regexec 和 strndup 的手册页。另一个建议是使用约定,即链接列表中的最后一项是标记列表末尾的哨兵。它简化了列表的管理。

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

typedef struct list_t {
  char *string;
  int   id;
  char *name;
  char *dim;
  char *size;
  char *location;
  char *date;
  struct list_t *next;
} list_t;

int main(int argc, char* argv[])
{
  FILE   *fp       = fopen("PhotoInfoBook.txt", "r");
  char   *line     = NULL;
  size_t  capacity = 0;
  list_t *head     = calloc(1, sizeof(list_t));
  list_t *iter     = head;
  regex_t re;
  regcomp(&re, "([0-9]+);([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)", REG_EXTENDED);
  regmatch_t capture[7];

  while (getline(&line, &capacity, fp) > 0) {
    if (regexec(&re, line, 7, capture, 0) == 0) {
      iter->string   = strdup(line);
      iter->id       = strtoul(line, NULL, 10);
      iter->name     = strndup(&line[capture[2].rm_so], capture[2].rm_eo - capture[2].rm_so + 1);
      iter->dim      = strndup(&line[capture[3].rm_so], capture[3].rm_eo - capture[3].rm_so + 1);
      iter->size     = strndup(&line[capture[4].rm_so], capture[4].rm_eo - capture[4].rm_so + 1);
      iter->location = strndup(&line[capture[5].rm_so], capture[5].rm_eo - capture[5].rm_so + 1);
      iter->date     = strndup(&line[capture[6].rm_so], capture[6].rm_eo - capture[6].rm_so + 1);
      iter->next     = calloc(1, sizeof(list_t));
      iter           = iter->next;
    }
  }

  for (iter = head; iter->next != NULL; iter = iter->next) {
    printf( "line      : %s", iter->string);
    printf( "        id: %d\n", iter->id);
    printf( "      name: %s\n", iter->name);
    printf( "       dim: %s\n", iter->dim);
    printf( "      size: %s\n", iter->size);
    printf( "  location: %s\n", iter->location);
    printf( "      date: %s\n", iter->date);
  }

  return 0;
}

推荐阅读