由端午不同类型的粽子所引发的思考------C语言实现筛选同一材料但不同馅的粽子

一.问题简介

端午之际,大家肯定吃过很多类型的粽子,大小,材料都不同,我现在想筛选出大小一致,但是类型不同的粽子,于是就想到了这个问题的解决方法,把粽子大小比作文件名,文件名是相同的,把粽子的类型(馅)比成文件名的后缀,后缀是不同的。

假设某个目录下有很多文件,我只要筛选出同一文件名的不同类型的文件,比如:目录下有1.txt,1.log,2.txt,2.log,2.ini,3.ini,4.log,4.txt。那么,我所需要的文件是2.txt,2.log,2.ini,其它的文件需要全部删除。

二.实现方法

其实实现这个功能需要以下几个步骤:
1.遍历指定目录下的文件名,并将不同的文件类型进行归类,且将所有文件名存入数组。
2.截取后缀名前的文件名,存入各自数组。
3.这三种数组进行三层循环比较,只保留文件名相同的文件,将其存入一个新数组。
4.遍历存入所有文件的数组,和新数组比较,若存入所有文件的数组不包含新数组的文件,那么就删除所有文件数组中的这个元素。

三.代码实现

#include<string.h>
#include<stdio.h>
#include<dirent.h>

char tempfiledir[128];
char tempfile[128];
char *p;
char *q;
char *t;
int sum=0;
int m=0;
char arrsum[100][100];
static int i=0;
static int j=0;
static int k=0;
char arrtxt[50][100];
char arrini[50][100];
char arrlog[50][100];
//将相同的文件名存入新的数组
char newfile[50][100];
//将不相同的文件名存入新的数组
char diffile[50][100];
//获取文件后缀之前的文件名
int getSplitString(char *path, char *name)
{
    char delim[] = ".";
    char *token;
    char *s = path;
    token = strsep(&s, ".");
    strcpy(name, token);
    return 0;
}

//读取目录下的所有文件,并按后缀分类将文件名保存进各自的数组
void readFileList(char *path)
{
	int ret;
	DIR *dp;
	char tmp[100] = {0};
	struct dirent *dirp;
	if((dp = opendir(path)) == NULL)
		printf("Can't open %s\n", path);
	while((dirp = readdir(dp)) != NULL)
	{
		if(strcmp(dirp->d_name,".")!=0&& strcmp(dirp->d_name,"..")!=0)
		{	
			strcpy(tempfiledir, dirp->d_name);
			p=strstr(tempfiledir,".txt");
			if(p!=NULL)
			{
				printf("file.txt:%s\n",tempfiledir);
				printf("i=%d\n",i);		
				ret = getSplitString(tempfiledir, tmp);
				strcpy(arrtxt[i],tempfiledir);
				printf("txt:%s\n",arrtxt[i]);
				i++;	
			}
			q=strstr(tempfiledir,".log");
			if(q!=NULL)
			{
				printf("file.log:%s\n",tempfiledir);
				printf("j=%d\n",j);			
				ret = getSplitString(tempfiledir, tmp);
				strcpy(arrlog[j],tempfiledir);
				printf("log:%s\n",arrlog[j]);
				j++;				
			}
			t=strstr(tempfiledir,".ini");
			if(t!=NULL)
			{
				printf("file.ini:%s\n",tempfiledir);
				printf("k=%d\n",k);
				ret = getSplitString(tempfiledir, tmp);
				strcpy(arrini[k],tempfiledir);
				printf("ini:%s\n",arrini[k]);
				k++;	
			}
		}
	}
	closedir(dp);
}

void DelFileList(char *path)
{
	
	int ret;
	DIR *Dp;
	char *P;
	char *Q;
	char *T;
	struct dirent *dirp;
	if((Dp = opendir(path)) == NULL)
		printf("Can't open %s\n", path);
	while((dirp = readdir(Dp)) != NULL)
	{
		if(strcmp(dirp->d_name,".")!=0&& strcmp(dirp->d_name,"..")!=0)
		{	
			strcpy(tempfile, dirp->d_name);
			strcpy(arrsum[sum],tempfile);
			sum++;
		}
	}
	for(int s=0;s<sum;s++)
	{
		int flag=0;
		for(int a=0;a<m;a++)
		{
			if(strcmp(newfile[a],arrsum[s])==0)
			{
				flag++;
			}
		}
		if(!flag)
		{
			printf("diff:%s\n",arrsum[s]);
			//文件夹下的这些文件不删
			if(strstr(arrsum[s],".json")==NULL && strstr(arrsum[s],"a.out")==NULL&& strstr(arrsum[s],"Samefilenames.c")==NULL)
				remove(arrsum[s]);
		}
	}
	closedir(Dp);
}


int main()
{
	//拼接
	char strtxt[5]=".txt";
	char strlog[5]=".log";
	char strini[5]=".ini";
	char filedir[] = "/home/yaowei/Desktop/files/test";
	readFileList(filedir);
	printf("i=%d\n",i);
	printf("j=%d\n",j);
	printf("k=%d\n",k);
	
	//进行三个数组判断是否有相同的文件名,保留到一个新的数组
	for(int x=0;x<i;x++)
	{
		for(int y=0;y<j;y++)
		{
			for(int z=0; z<k;z++)
			{
				if(strcmp(arrtxt[x],arrlog[y])==0&&strcmp(arrtxt[x],arrini[z])==0&&strcmp(arrlog[y],arrini[z])==0)
				{
					printf("yes\n");
					printf("arrtxt:%s\n",arrtxt[x]);
					printf("arrlog:%s\n",arrlog[y]);
					printf("arrini:%s\n",arrini[z]);
					//字符串拼接,文件名+后缀名
					strcpy(arrtxt[x]+strlen(arrtxt[x]),strtxt);
					strcpy(arrlog[y]+strlen(arrlog[y]),strlog);
					strcpy(arrini[z]+strlen(arrini[z]),strini);
					//将相同文件名的所有三种类型文件保存进新的数组
					strcpy(newfile[m],arrtxt[x]);
					m++;
					strcpy(newfile[m],arrlog[y]);
					m++;
					strcpy(newfile[m],arrini[z]);
					m++;	
				}
			}
		}
	}
	//打印三种相同文件名类型的文件总数
	printf("samefilenames:%d\n",m);
	//遍历此新的数组
	for(int X=0;X<m;X++)
	{
		printf("same files:%s\n",newfile[X]);
	}
	DelFileList(filedir);
	return 0;
}

各函数说明:
getSplitString
分割后缀名,获取后缀名前的文件名。
readFileList
遍历文件夹下的所有文件,并按后缀分类将文件名保存进各自的数组。
DelFileList
将保存所有文件名的数组和筛选过相同文件名并保存的数组进行比较,若所有文件名的数组中不含筛选过相同文件名的数组的元素,那么就删除这个文件名元素。

四.实例演示

文件夹下有以下文件
在这里插入图片描述
执行a.out,./a.out
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看出,执行完程序后,现在文件夹下保留了2.ini,2.log,2.txt,a.out和Samefilename.c(a.out和Samefilename.c是代码中非删除部分)。

总结:这部分只是演示了三种类型的文件,如果有更多的类型文件,可以多加几个数组,判断时多加几层循环,这个方法是最简单容易理解的,有更好的方法大家可以在评论区留下方法。

祝大家端午安康。

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值