端午之际,大家肯定吃过很多类型的粽子,大小,材料都不同,我现在想筛选出大小一致,但是类型不同的粽子,于是就想到了这个问题的解决方法,把粽子大小比作文件名,文件名是相同的,把粽子的类型(馅)比成文件名的后缀,后缀是不同的。
假设某个目录下有很多文件,我只要筛选出同一文件名的不同类型的文件,比如:目录下有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#include #include 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 %sn", 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:%sn",tempfiledir); printf("i=%dn",i); ret = getSplitString(tempfiledir, tmp); strcpy(arrtxt[i],tempfiledir); printf("txt:%sn",arrtxt[i]); i++; } q=strstr(tempfiledir,".log"); if(q!=NULL) { printf("file.log:%sn",tempfiledir); printf("j=%dn",j); ret = getSplitString(tempfiledir, tmp); strcpy(arrlog[j],tempfiledir); printf("log:%sn",arrlog[j]); j++; } t=strstr(tempfiledir,".ini"); if(t!=NULL) { printf("file.ini:%sn",tempfiledir); printf("k=%dn",k); ret = getSplitString(tempfiledir, tmp); strcpy(arrini[k],tempfiledir); printf("ini:%sn",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 %sn", 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 int flag=0; for(int a=0;a if(strcmp(newfile[a],arrsum[s])==0) { flag++; } } if(!flag) { printf("diff:%sn",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=%dn",i); printf("j=%dn",j); printf("k=%dn",k); //进行三个数组判断是否有相同的文件名,保留到一个新的数组 for(int x=0;x for(int y=0;y for(int z=0; z if(strcmp(arrtxt[x],arrlog[y])==0&&strcmp(arrtxt[x],arrini[z])==0&&strcmp(arrlog[y],arrini[z])==0) { printf("yesn"); printf("arrtxt:%sn",arrtxt[x]); printf("arrlog:%sn",arrlog[y]); printf("arrini:%sn",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:%dn",m); //遍历此新的数组 for(int X=0;X printf("same files:%sn",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是代码中非删除部分)。
总结:这部分只是演示了三种类型的文件,如果有更多的类型文件,可以多加几个数组,判断时多加几层循环,这个方法是最简单容易理解的,有更好的方法大家可以在评论区留下方法。
祝大家端午安康。



