2021-07-24

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

四、运行结果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值