c - 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);
}
关于我应该如何进行的任何想法?
解决方案
有几个函数可以使 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;
}
推荐阅读
- c - 如何从 64 中获得 63 位
- c++ - 释放动态内存
- c++ - C++中具有列表变量的类对象的动态内存分配机制
- android - 如何在 Android 的文件管理器中打开 uri
- python - docker-compose up django 和 mysql 的错误
- azure-devops - Azure DevOps 发布管道 - 自定义变量的下拉列表
- android - ViewBinding 与 DataBinding 有冲突
- lua - 将中间结果存储在 lua openresty 中的临时变量中会产生不同的结果
- php - 提交表单提交后目标页面不显示
- angular - 如果 MatSelctionList,如何获取屏幕上可见的项目数量?