C语言:搜索目录指定后缀文件并保存在链表中
前言
查找指定目录,以 gif 和jpg为后缀的文件,并将文件信息保存在链表中。
提示:以下是本篇文章正文内容,具体说明在代码段中均有注释
一、链表的基本操作
/*
带头结点的单链表
*/
#ifndef LINKLIST_H_
#define LINKLIST_H_
#include <string.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
typedef struct Node
{
int size; // 统计链表的大小
char data[40]; //保存文件名
struct Node* next; // 结点的指针域
}Node;
typedef Node LinkList;
// 初始化一个空链表
LinkList* init_link_list();
// 在链表尾部添加结点
void push_back(LinkList* list, char* value); //
// 遍历链表
void print_list(LinkList* list);
#endif
#include "linklist.h"
#include <stdio.h>
#include <stdlib.h>
// 初始化一个空链表
LinkList* init_link_list()
{
Node* head = malloc(sizeof(Node));
head->next = NULL;
head->size = 0;
return head;
}
// 在链表尾部添加结点
void push_back(LinkList* list, char* value)
{
// 创建一个新结点
Node* new_node = malloc(sizeof(Node));
// 把给定的值value,做为新结点的数据域
strcpy(new_node->data , value);
// 把新结点的指针域指空
new_node->next = NULL;
// 如果链表为空,则头指针指向这个新结点即可
if (list->next == NULL)
{
list->next = new_node;
}
// 如果链表不为空,则把新结点链接到末尾
else
{
// 定义一个工作指针,用于遍历整个链表
Node* p = NULL;
// 工作指针指向第一个结点
p = list;
while (1)
{
if (p->next != NULL)
p = p->next;
if (p->next == NULL)
break;
}
// 使最后一个结点的指针域,指向新结点
p->next = new_node;
}
//更新链表大小
list->size++;
}
// 遍历链表
void print_list(LinkList* list)
{
if (list == NULL || list->next == NULL)
return;
//定义一个工作指针,用于遍历整个链表
Node* p = list->next;
while (1)
{
printf("%s\n", p->data);
//printf("%d ",p->size);
p = p->next;
if (p == NULL)
break;
}
printf("\n");
}
二、目录的基本操作
#ifndef DIR_H_
#define DIR_H_
//加入链表头文
#include "linklist.h"
//定义过滤函数
int file_filter(char* filename);
//定义目录操作函数
void open_dir(const char* path);
#endif
#include "dir.h"
int file_filter(char *filename)
{
int flag = 0;
char *str;
str = strrchr(filename,'.');
if(strcmp(str,".jpg") == 0)
{
//判断为 jpg 文件
flag = 1;
}
if(strcmp(str,".gif") == 0)
{
//判断为 png 文件
flag = 2;
}
return flag;
}
//打开目录
void open_dir(const char* path)
{
LinkList * listjpg = init_link_list();
LinkList * listgif = init_link_list();
//打开目录
DIR *pDir = opendir(path);
if(pDir == NULL)
{
perror("opendir error \n");
return ;
}
//循环读取目录
struct dirent *pd = NULL;
while((pd = readdir(pDir)) != NULL )
{
if(strcmp(pd->d_name,".")==0||strcmp(pd->d_name,"..")==0)
{
//过滤掉 .文件
continue;
}
//判断文件为普通文件
if(pd->d_type== DT_REG)
{
switch(file_filter(pd->d_name))
{
case 1:
//判断为jpg,入jpg链表
push_back(listjpg,pd->d_name);
break;
case 2:
//判断为gif,入gif链表
push_back(listgif,pd->d_name);
break;
default:
break;
}
}
}
//关闭目录
closedir(pDir);
//打印.jpg文件的信息
print_list(listjpg);
printf("linklist size= %d\n",listjpg->size);
//打印 .gif的信息
print_list(listgif);
printf("linklist size= %d\n",listgif->size);
}
三、测试代码
注:测试目录作为参数在编译时传入
编译软件: vscode
编译环境: windows子系统 Ubuntu18.04
#include"dir.h"
int main(int argc, char* argv[])
{
if(argc != 2)
{
fprintf(stderr, "usage: %s filename\n", argv[0]);
exit(1);
}
open_dir(argv[1]);
}
四、运行结果