Linux使用双向链表实现图片、音乐、视频的切换和删除功能

Linux检索目录下的后缀文件(.bmp .avi .mp3),并将文件名存入链表中

一、双向链表的实现

1.创建双向链表

  1. 创建双向链表 结构体
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

//创建链表结构体
typedef struct bmp_node{
        char data[32];  //数据域    
        struct bmp_node *prev;   //指针域    
        struct bmp_node *next;
}BmpNode;

2.创建链表头结点

//创建双向链表头
BmpNode *D_R_List_Create(void)
{    
  //申请堆空间    
  BmpNode *list=(BmpNode *)malloc(sizeof(BmpNode));
    if(list == NULL)
    {        
      perror("malloc failed");
      return NULL;    
    }
    list->prev=list;
    list->next=list;        
    return list;
}

2.链表节点添加

//双向链表节点添加(尾插法)
bool list_add_node_tail(BmpNode *head,char *data)
{
   //申请堆空间    
   BmpNode *newnode=(BmpNode *)malloc(sizeof(BmpNode));
   if(newnode == NULL)
   {    
      perror("malloc failed");    
      return false;
   }    
   //对新结点赋值    
   strcpy(newnode->data,data);    
   newnode->prev=newnode;    
   newnode->next=newnode;    
   //处理后继指针    
   head->prev->next=newnode;    
   newnode->next=head;    
   //处理前继指针    
   newnode->prev=head->prev;    
   head->prev=newnode;
   return true;
}

3.链表删除

//链表节点删除
bool list_node_remove(BmpNode *head,char *data)
{    
  BmpNode *p=head->next;    
  while(p != head)    
  {        
    if(p->data == data)        
    {            
      printf("删除节点成功\n");            
      p->prev->next=p->next;            
      p->next->prev=p->prev;            
      free(p);            
      return true;                    
    }        
   p=p->next;    
  }    
 printf("删除节点失败:没有这个节点\n");    
 return false;    
}

4.链表数据显示

//链表数据显示
void D_R_List_Show_Data(BmpNode *head)
{    
  BmpNode *p=head->next;    
  printf("链表数据为:");    
  while(p!=head)    
  {      
    printf("%s",p->data);        
    p=p->next;    
  }    
 printf("\n");
}

5.链表销毁

//链表销毁
void list_destory(BmpNode *head)
{   
  int i;    
  BmpNode *p=head->next;    
  while(p != head)    
  {      
    i++;        
    p=p->next;        
    free(p->prev);            
  }    
 printf("一共释放%d个节点",i);    
 free(head);    
 printf("链表销毁成功\n");    
}

二、查找所需要的文件

1.检索目录下.bmp图片文件并保存到双向链表中,成功返回0

int Search_Dir(BmpNode *head,char *dirpath)
{      
  DIR *dp=opendir(dirpath);  //打开目录    
  if(NULL == dp)    
  {      
    perror("opendir false");        
    return -1;            
  }         
  struct dirent *fp;    
  char bmp_buf[32];    
  while(fp=readdir(dp))    
  {      
    if(strstr(fp->d_name,".bmp"))  //检索bmp文件        
    {                      
      sprintf(bmp_buf,"%s/%s",dirpath,fp->d_name);  //字符串打包                        
      list_add_node_tail(head,bmp_buf);//尾插法插入链表            
      memset(bmp_buf,0,sizeof(bmp_buf));  //清空数组                    
    }    
  }    
  D_R_List_Show_Data(head);  //显示链表节点数据    
  closedir(dp);  //关闭文件        
  return 0;
}

2.检索目录下.avi视频文件,并保存到双向链表中,成功返回0

//检索目录里AVI文件并存入链表
int Search_Dir_Avi(BmpNode *head,char *dirpath)
{      
  DIR *dp=opendir(dirpath);  //打开目录    
  if(NULL == dp)    
  {      
    perror("opendir false");        
    return -1;            
  }         
  struct dirent *fp;    
  char bmp_buf[32];    
  while(fp=readdir(dp))    
  {      
    if(strstr(fp->d_name,".avi"))  //检索文件        
    {                      
      sprintf(bmp_buf,"%s/%s",dirpath,fp->d_name);  //字符串打包            
      list_add_node_tail(head,bmp_buf);  //尾插法插入链表            
      memset(bmp_buf,0,sizeof(bmp_buf));  //清空数组                    
    }    
  }    
  D_R_List_Show_Data(head);  //显示链表节点数据    
  closedir(dp);  //关闭文件        
  return 0;
}

2.检索目录下.mp3音乐文件,并保存到双向链表中,成功返回0

//检索目录里MP3文件数据并存入链表
int Search_Dir_Mp3(BmpNode *head,char *dirpath)
{  
  DIR *dp=opendir(dirpath);  //打开目录    
  if(NULL == dp)    
  {      
    perror("opendir false");      
    return -1;            
  }         
  struct dirent *fp;    
  char bmp_buf[32];    
  while(fp=readdir(dp))    
  {      
    if(strstr(fp->d_name,".mp3"))  //检索文件        
    {                      
      sprintf(bmp_buf,"%s/%s",dirpath,fp->d_name);  //字符串打包            
      list_add_node_tail(head,bmp_buf);  //尾插法插入链表            
      memset(bmp_buf,0,sizeof(bmp_buf));  //清空数组                    
    }    
  }    
  D_R_List_Show_Data(head);  //显示链表节点数据    
  closedir(dp);  //关闭文件        
  return 0;        
}

三、双向链表实现的功能

1.实现图片的切换和删除功能

(1)切换上一张、下一张图片

BmpNode *list=D_R_List_Create();  //创建链表    
Search_Dir(list,"./picture");  //检索目录
if(...)
{
  p=p->next;            
  if(p==list)            
  {              
    p=p->next;            
  }
  show_bmp(800,480,0,0,p->data);
}
if(...)
{
  p=p->prev;
  if(p==list)
  {
    p=p->prev;
  }
  show_bmp(800,480,0,0,p->data);
}

(2)删除图片功能

if(...)
{
  remove(p->data);                
  printf("删除图片成功!\n");                
  list_node_remove(list,p->data);                
  p=p->next;                
  if(p==list)                
  {                    
    p=p->next;               
  }                
  Show_Bmp(640,480, 0, 0, p->data);
}

2.视频和音乐的切换和删除功能和图片的一样的操作

四、实现的难点和总结

(1)strcpy()和“=”直接赋值的区别,个人认为strcpy用于对字符串的堆空间进行拷贝,不改变自身的地址,“=”直接赋值是把字符串的首地址赋值给变量,自身的地址会发生改变。

详情可参考:https://blog.csdn.net/qq_40737025/article/details/103951297
(2)注意双向链表的前指针和尾指针,应指针内容较为抽象,建议画图加深理解双向链表

(3)常用的函数和作用

malloc(sizeof(BmpNode)) :		
//申请和BmpNode一样大的栈空间

strcpy(newnode->data,data);		
//把data的内容拷贝到newnode->data中

free(p);					
//释放p节点的栈空间

perror("opendir false");			
//打印错误信息

DIR *dp=opendir(dirpath); 	       
//打开dirpath路径下的目录,成功则返回__dirstream  的结构体,失败返回一个空的指针

strstr(fp->d_name,".bmp");		
//若".bmp"是fp->d_name的子串,则返回".bmp"在fp->d_name的首次出现的地址;否则,则返回NULL

memset(bmp_buf,0,sizeof(bmp_buf));  
//清空bmp_buf数组
  • 8
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序小鹿

博主不差钱,点个赞就行哈哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值