蠻有意思的,主要考查鏈表和樹結構的知識。spa
代碼以下:指針
******************************************************************************/ #include "FileManager.h" //#include <stdafx.h> #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; }