蛮有意思的,主要考查链表和树结构的知识。
代码如下:
******************************************************************************/#include "FileManager.h"//#include#include "stdio.h"#include "string.h"#include "map"#include "malloc.h"#define NO 0#define OK 1//文件定义 链表结构//文件定义struct file{ char filename[300]; struct file *nextf;//p310 链表 *nextf 是指针变量,指向结构体变量,存放下一个节点的地址 };//struct dir{ char dirName[300]; struct dir* subDir; //子目录 struct dir* borDir; //兄弟目录 struct dir* parDir; //父目录 struct file* fhead;//当前目录的文件};//全局根目录初始化 struct dir root={"root",NULL,NULL,NULL,NULL};/*功能描述:根据目录名获得目录指针参数描述:DirName 目录名称 cur 当前目录指针返回值:所查询目录名称的目录指针*/struct dir* getDirByName(const char* DirName,struct dir* cur){ if(NULL==cur) { return NULL; } if(0==strcmp(cur->dirName,DirName)) { return cur; } struct dir* res; res=getDirByName(DirName,cur->borDir); if(NULL==res) { res=getDirByName(DirName,cur->subDir); } return res;} /* 功能描述:根据文件名获得文件指针 参数描述:FileName-文件名称 cur-当前目录指针 返回值:所查询文件名称的目录指针 */struct file* getFileByName(const char * FileName,struct dir*cur){ struct file* p=cur->fhead; while(NULL!=p) { if(0==strcmp(p->filename,FileName)) { return p; } p=p->nextf; } p=NULL; if(NULL!=cur->borDir) p=getFileByName(FileName,cur->borDir); if(NULL==p&&NULL!=cur->subDir) p=getFileByName(FileName,cur->subDir); return p;}/* 功能描述:判断指定名称目录是否已经存在 参数描述:DirName-目录名称 返回值:OK-存在 NO-不存在 */int isDirNameExist(const char* DirName){ struct dir* cur=getDirByName(DirName,&root); if(NULL==cur) return NO; return OK;} /* 功能描述:判断指定名称文件是否已经存在 参数描述:FileName-文件名称 返回值:OK-存在 NO-不存在 */ int isFileNameExist(const char* FileName){ struct file* cur=getFileByName(FileName,&root); if(NULL==cur) return NO; return OK;} /* 功能描述:在指定目录下创建新目录 参数描述:ParentDirName-父目录名称 DirName-新目录名称 返回值:0-创建成功 -1-创建失败 */int CreateDir(const char * ParentDirName, const char * DirName){ //检查父目录、待创建目录名称是否已存在 if(NULL==ParentDirName||OK!=isDirNameExist(ParentDirName)||NULL==DirName||OK==isDirNameExist(DirName)) { return -1; } struct dir* parDir=getDirByName(ParentDirName,&root); struct dir* curDir=(struct dir*)malloc(sizeof(struct dir)); //如果申请空间失败 if(NULL==curDir) return -1; if(NULL==parDir) { free(curDir); return -1; }/**********新目录对象赋值开始***************/ curDir->fhead=NULL ; curDir->subDir=NULL; curDir->borDir=NULL; curDir->parDir=parDir; strcpy(curDir->dirName,DirName);/**********新目录对象赋值开始***************/ //将新目录插入指定位置 if(NULL==parDir->subDir) { parDir->subDir=curDir; return 0; } struct dir* p=NULL,*q=NULL; p=parDir->subDir; q=p->borDir; p->borDir=curDir; curDir->borDir=q; return 0;} /* 功能描述:清除子目录 参数描述: 返回值: */void CleanSubDir(struct dir* curDir){ if(NULL==curDir) return; struct file* fhead=curDir->fhead; struct file* fnext=NULL; while(NULL!=fhead) { fnext=fhead->nextf; free(fhead); fhead=fnext; } curDir->fhead=NULL; if(NULL!= curDir->subDir) { CleanSubDir(curDir->subDir); free(curDir->subDir); curDir->subDir=NULL; } return;}/*功能描述:删除指定目录参数描述:DirName-目录名称返回值:无*/void DeleteDir(const char * DirName){ //检查目录的存在情况、根目录不能删除 if(NULL==DirName||OK!=isDirNameExist(DirName)||0==strcmp("root",DirName)) return; struct dir* curDir=getDirByName(DirName,&root); struct dir* parDir=curDir->parDir; //清理当前目录下的所有文件及目录 CleanSubDir(curDir); //如果父目录下头指针指向这个目录,那么将这个头指针赋给它的兄弟目录,将这个指针free掉 if(parDir->subDir==curDir) { parDir->subDir=curDir->borDir; free(curDir); return; } //如果父目录头指针不是指向这个目录,那么遍历父目录指针的子目录,找到这个目录的指针,将这个指针解放掉。将其释放掉。即a->b->c 删除b ,那么a->c struct dir* p=parDir->subDir; struct dir* q=NULL; while(NULL!=p) { q=p; p=p->borDir; if(p==curDir) { q->borDir=p->borDir; free(p); break; } } return;}/*功能描述:判断两个目录是否存在父子目录关系参数描述:parDir-父目录名称 subdir-子目录名称返回值:OK-是父子目录关系 NO-非父子目录关系*/int isTheSubDir(struct dir* parDir,struct dir* subdir){ struct dir* p=subdir; while(NULL!=p) { if(p->parDir==parDir) return OK; p=p->parDir; } return NO;}/*功能描述:移动目录参数描述:SrcDirName-待移动目录名称 DestDirName-目标移动目录名称返回值:0-移动成功 -1-移动失败*/int MoveDir(const char * SrcDirName, const char * DestDirName){ //检查两个目录的存在情况、根节点不移动、两个目录不能相同 if(NULL==SrcDirName||NULL==DestDirName||OK!=isDirNameExist(SrcDirName)||OK!=isDirNameExist(DestDirName)||0==strcmp(SrcDirName,DestDirName)||0==strcmp("root",SrcDirName)) return -1; struct dir *srcDir=getDirByName(SrcDirName,&root); struct dir *desDir=getDirByName(DestDirName,&root); //目标目录不能使用源目录的子目录、源目录不能是目标目录的直接子目录 if(OK==isTheSubDir(srcDir,desDir)||srcDir->parDir==desDir) return -1; /********************将源目录从其父目录剥离********************/ //如果src 的父目录的子目录头指针指向src ,那么将src的父目录的子目录的头指针指向src 的兄弟目录 if(srcDir->parDir->subDir==srcDir) { srcDir->parDir->subDir=srcDir->borDir; } //如果src 的父目录的子目录头指针不是指向src ,那么遍历src的父目录的子目录,找出src,然后将src的指针删除掉 a->b->c a->c 将b(src)删除 else { struct dir* p,*q; q=srcDir->parDir->subDir; p=q->borDir; while(NULL!=p) { if(0==strcmp(p->dirName,SrcDirName)) { q->borDir=p->borDir; break; } q=p; p=p->borDir; } }/********************将源目录从其父目录剥离成功********************/ //将源目录移动到目标目录之下 srcDir->parDir=desDir; if(NULL==desDir->subDir) { desDir->subDir=srcDir; srcDir->borDir=NULL; } else { srcDir->borDir=desDir->subDir; desDir->subDir=srcDir; } return 0;}/*功能描述:在指定目录下创建文件参数描述:FileName-文件名称,curDir-当前目录返回值:0-创建成功 -1-创建失败*/int CreateFile(const char * DirName, const char * FileName){ //检查目录名称、待创建文件名称的存在情况 if(NULL==DirName||NULL==FileName||OK!=isDirNameExist(DirName)||OK==isFileNameExist(FileName)) return -1; struct dir* curDir=getDirByName( DirName, &root); struct file* newFile=(struct file*)malloc(sizeof(struct file)); //判断申请空间是否成功 if(NULL==newFile) { return -1; } //新文件属性赋值 newFile->nextf=NULL; strcpy(newFile->filename,FileName); //将文件插入指定位置 if(NULL==curDir->fhead)//如果原来的目录下没有文件 { curDir->fhead=newFile;//直接将文件赋给它 } else { newFile->nextf=curDir->fhead;//先指向当前已有的文件的 兄弟文件指针 curDir->fhead=newFile; //在赋值 } return 0;}/*功能描述:删除指定名称的文件-由DeleteFile调用参数描述:FileName-文件名称,curDir-当前目录返回值:NO-未删除 OK-删除成功*/int DeleteFileByName(const char * FileName,struct dir* curDir){ if(NULL==curDir) return NO; struct file*p=curDir->fhead; struct file*q=NULL; if(NULL!=p) { if(0==strcmp(p->filename,FileName)) { curDir->fhead=p->nextf; free(p); return OK; } else //?这是干啥的? { p=curDir->fhead; q=p->nextf; while(NULL!=q) { if(0==strcmp(q->filename,FileName)) { p->nextf=q->nextf; free(q); return OK; } p=q; q=q->nextf; } } } int res=NO; res=DeleteFileByName(FileName,curDir->borDir); if(NO==res) res=DeleteFileByName(FileName, curDir->subDir); return res; } /*功能描述:删除指定名称的文件参数描述:FileName-文件名称返回值:无*/void DeleteFile(const char * FileName){ if(NULL==FileName||OK!=isFileNameExist(FileName)) return; DeleteFileByName(FileName,&root); return;}/*功能描述:计算指定目录下的文件数量(包括子目录)参数描述:DirName-目录名称 fileNum-文件数量(输出参数)返回值:无*/void calFileNum(struct dir*curDir,unsigned int *fileNum){ if(NULL==curDir) return ; struct file* filep=curDir->fhead; while(NULL!=filep) { (*fileNum)++; filep=filep->nextf; } if(NULL!=curDir->borDir) calFileNum(curDir->borDir,fileNum); if(NULL!=curDir->subDir) calFileNum(curDir->subDir,fileNum); }/*功能描述:获取指定目录下的文件数量(包括子目录)参数描述:DirName-目录名称返回值:指定目录下的文件数量*/unsigned int GetFileNum(const char * DirName){ unsigned int fileNum=0; if(NULL==DirName||OK!=isDirNameExist(DirName)) return fileNum; struct dir*curDir=getDirByName(DirName, &root); if(NULL==curDir) return fileNum; //计算当前目录下的文件数量 struct file* filep=curDir->fhead; while(NULL!=filep) { fileNum++; filep=filep->nextf; } //计算子目录下文件的数量 if(NULL!=curDir->subDir) calFileNum(curDir->subDir,&fileNum); return fileNum;}/*功能描述:清空文件系统所有信息参数描述:curDir-当前目录返回值:无*/void CleanDir(struct dir*curDir){ if(NULL==curDir) return; struct file* fhead=curDir->fhead; struct file* fnext=NULL; while(NULL!=fhead) { fnext=fhead->nextf; free(fhead); fhead=fnext; } curDir->fhead=NULL; if(NULL!= curDir->borDir) { CleanDir( curDir->borDir); free( curDir->borDir); curDir->borDir=NULL; } if(NULL!= curDir->subDir) { CleanDir(curDir->subDir); free(curDir->subDir); curDir->subDir=NULL; } return;}void Clear(void){ CleanDir(&root); return;}