该文章为递归寻找目录下目标文件(待完善,但是能用)

首先是链表,目前设置为双向链表还未简化.

头文件bothlist.h

#ifndef __BOTHLIST_H__
#define __BOTHLIST_H__

struct list_head *create_list_head(void);
struct list_head *add_node(struct list_head * listhead ,char * newcs, int d);
struct list_head * print_list_head(struct list_head *list);
struct list_head* traverse_dir(char *dirnameA, struct list_head* list1); // 遍历文件夹寻找目标
struct list_head* find_dir(char *dirnameA); //进入目标路径

typedef int ElemType;
//32位下这个结构体是8个字节
//64位下这个结构体是16个字节
struct Node
{
	ElemType data;//"数据域":保存数据元素
	char cs[500];
	struct Node *next;//"指针域":保存下一个数据元素的地址
	struct Node *pre;				  //实际上就是用来保存数据与数据之间的关系的
};
struct list_head
{
	struct Node *first; //指向链表中的第一个节点(首节点)
	struct Node *last;	//指向链表中的最后一个节点(尾结点)
	int num;			//节点的个数
	//char list_name[512];	//链表的名字
	//..
};

#endif

链表c程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bothlist.h"

//头结点


//创建一个带头结点的单链表
struct list_head *create_list_head(void)
{
	//开辟一块新的内存空间给头结点并且对头结点的成员变量进行初始化
	struct list_head *listhead = malloc(sizeof(struct list_head));
	listhead->first = listhead->last = NULL;
	listhead->num = 0;
	return listhead;
}
//将一条带头结点的单链表进行打印

struct list_head *add_node(struct list_head * listhead ,char * newcs, int d)
{
		//开辟新的节点保存获取到的数据
		struct Node *pnew = malloc(sizeof(struct Node));
		pnew->data = d;
		strcpy( pnew->cs ,newcs);
		pnew->next = NULL;
		pnew->pre = NULL;
		//将新节点尾插到新的带头结点的链表中去
		if(listhead->first == NULL)
		{
			listhead->first = listhead->last = pnew;
			listhead->first->pre = NULL;
			listhead->last->pre = NULL;	
		}
		else//尾插法
		{
			listhead->last->next = pnew;
			pnew->pre = listhead->last;
			listhead->last = pnew;
			listhead->last->next = listhead->first;//修改时间9 23 21:10
			listhead->first->pre = listhead->last;
		}
		//链表中节点的个数加1
		listhead->num++;
	
	//返回头节点的地址
	return listhead;
}
//将一条带头结点的单链表进行打印

struct list_head * print_list_head(struct list_head *list)
{
	struct Node*p = list->first;
    int times = list->num; 
	while(times--)
	{
		printf("%s \n",p->cs);
		p = p->next;
	}
	putchar('\n');
	printf("此链表中节点的个数为%d\n",list->num);
}

//释放内存
void free_list_head(struct list_head *list)
{
	struct Node *p = list->first;
	while(list->first)
	{
		p = list->first;
		list->first = list->first->next;
		p->next = NULL;
		//释放摘下来的节点
		free(p);
	}
	//释放头节点
	free(list);
}
//输出倒数第k个节点的地址
struct list_head* sentry(struct list_head *list ,int k)
{
	if (k>list->num)
	{
		printf("???手欠???\n");	
	}
	else
	{
		struct Node* p1 = list->first;
		struct Node* p2 = list->first;
		while(k--)
		{
			p1 = p1->next;
		}
		while(p1)
		{
			p1 = p1->next;
			p2 = p2->next;
		}
		printf("%c的地址为%p\n",p2->data,&(p2->data));
	}
}
void print_list_last(struct list_head *list)
{
	struct Node*p = list->last;
	while(p)
	{
		printf("%s \n",p->cs);
		p = p->pre;
	}
	putchar('\n');
	printf("此链表中节点的个数为%d\n",list->num);
}

功能函数find_target.c

#include <stdio.h>       //寻找目标文件.c .cpp
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include "bothlist.h"
/*
	func:遍历目录A的子文件

	返回值:0成功  -1失败
*/
struct list_head* traverse_dir(char *dirnameA, struct list_head* list1)
{
//	printf("a = %s line = %d func = %s\n",dirnameA,__LINE__,__FUNCTION__);
	
	//1、打开目录
	DIR *d = opendir(dirnameA);
	if(d == NULL)
	{
		perror("open dirname A error");
	//	printf("dirname = %s\n",dirnameA);
		return NULL;
	}
	
	int qu = 0; //区别jgp和bmp
	int need = 0; //使用该数字去截取后缀
	
	//2、读取该目录下所有的子文件/子目录
	while(1)
	{
		
		struct dirent * p = readdir(d);//读取目录项
		if(p == NULL)//如果读完了
		{
			break;
		}
		//3、判断目录项中文件名是否是. ..,如果是,就跳过
		if(strcmp(".",p->d_name) == 0  || strcmp("..",p->d_name) == 0)
		{
			continue;
		}
		//4、如果不是,判断是目录还是文件
		struct stat statbuf;
		
		//因为进程的工作路径问题,只能直接访问当前目录下的文件
		char cbuf[2560] = {0};
		strcpy(cbuf,dirnameA);//dirnameA -> "/home/china"
		cbuf[strlen(cbuf)] = '/'; //buf -> "/home/china" => "/home/china/"
		strncat(cbuf,p->d_name,strlen(p->d_name)); //p->d_name-> "1.txt" => "/home/china/1.txt
		
		stat(cbuf, &statbuf);//这个文件在哪一个路径下面呢? dirnameA => dirnameA/p->d_name
	//	printf("%s",check);
		need = strlen(cbuf)-2; //截取后缀.xxx 
		if(strcmp(".c",cbuf+need) == 0)
		{
			qu = 2;
			
			list1 = add_node(list1,cbuf,qu);
			
		}
		if(strcmp(".cpp",cbuf+need-2) == 0)
		{
			qu = 1;
			list1 =add_node(list1,cbuf,qu);
		}	
		if(S_ISDIR(statbuf.st_mode)) //如果是目录再找
		{
			traverse_dir(cbuf,list1); 
		}
	
	}

	closedir(d); //关闭目录
return list1;
}

/*
	func:寻找MP3
	返回值:0成功  -1失败
*/

struct list_head* find_dir(char *dirnameA)
{
	if(dirnameA == NULL)//判断输入是不是有问题
	{
		return NULL;
	}
	struct list_head * list1;
	list1 = create_list_head();
	list1 = traverse_dir(dirnameA,list1);	
	//print_list_head(list1);
return list1;
}
int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        printf("./a.out road\n");
        exit(EXIT_FAILURE);
    }
    struct list_head* list1 = find_dir(argv[1]);
    print_list_head(list1);
return 0;
}

太晚了,有时间再简化 这是直接从一个项目中搬出来的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值