Introduction This code helps us to list all the files and folders within a directory and sub-directory. Background The code should be written in win32 projects as a console application. Code: #include <windows.h> #include <string.h> #include <stdio.h> #include <conio.h> //macro #define DEFAULTSIZE 10 #define INTERNALTRAVERSING 1 #define FIRSTLEVELTRAVERSING 0 int main(int argc, char *argv[]) { char* DirSpec; int traversal; char* substring; // argv[1]="c:"; // argv[2]="/s"; // argc=2; printf ("Target directory is %s.\n", argv[1]); DirSpec=(char*)calloc ( strlen(argv[1])+1,sizeof(char)) strcpy(DirSpec,argv[1]); printf("Name \t\t\t\t Dir/Size \t Created \t Attributes"); if(strcmp(argv[2],"/s")==0){ traversal=INTERNALTRAVERSING; }else{ traversal=FIRSTLEVELTRAVERSING; } if(FindMatch(DirSpec)!=1){ if(GetFileAttributes(DirSpec)==FILE_ATTRIBUTE_DIRECTORY){ substring=NULL; strcat(DirSpec,"\\*"); }else{ substring=GetSubstring(DirSpec); } }else{ substring=NULL; } WalkFolder(DirSpec,traversal,substring); _getch(); free(DirSpec); return (0); } void Display(WIN32_FIND_DATA *pFindFileData) { LPSYSTEMTIME lpst; lpst=(LPSYSTEMTIME)calloc(1,sizeof(SYSTEMTIME)); //allocates memory for lpst. FileTimeToSystemTime(&pFindFileData->ftCreationTime,lpst); //converts the time to system time. if(pFindFileData->nFileSizeLow==0) printf ("\n %s \t\t\t\t <Dir>\t\t ", pFindFileData->cFileName); else printf("\n %s \t %d \t ",pFindFileData->cFileName,pFindFileData->nFileSizeLow); printf("%d/%d/%d %d:%d:%d \t ",lpst->wDay,lpst->wMonth,lpst->wYear,lpst->wHour,lpst->wMinute,lpst->wSecond); PrintFileAttribute(pFindFileData->dwFileAttributes); free(lpst); //frees the memory allocated for lpst. } void WalkFolder (char* pPath,BOOL pSub_folders,char* pSubstr) { WIN32_FIND_DATA FindFileData; HANDLE hFind; DWORD dwError; char ** allpath; int index=0,i; static int no_of_files=0; static int no_of_folders=0; printf("\n ................................................................."); printf("\n The display is for the path %s \n ", pPath); allpath=(char **)calloc(DEFAULTSIZE,sizeof(char*)); hFind= INVALID_HANDLE_VALUE; hFind = FindFirstFile(pPath, &FindFileData); if (hFind == INVALID_HANDLE_VALUE && pSub_folders!=INTERNALTRAVERSING ) { printf ("Invalid file handle. Error is %u\n", GetLastError()); } else if(hFind!= INVALID_HANDLE_VALUE && pSubstr !=NULL){ PrintFileInfo(hFind,&FindFileData,&no_of_files); } if(pSubstr !=NULL && pSub_folders==INTERNALTRAVERSING){ RemoveSubString(pPath,pSubstr); hFind = FindFirstFile(pPath, &FindFileData); } do{ if(pSubstr==NULL){ Display(&FindFileData); } if(FindFileData.nFileSizeLow==0 && (strcmp(FindFileData.cFileName,".")!=0) && (strcmp(FindFileData.cFileName,"..")!=0)&& pSub_folders==INTERNALTRAVERSING){ if((index+1)%DEFAULTSIZE==0 && index>0){ allpath=(char **)realloc(allpath,(index+DEFAULTSIZE)); } allpath[index]=GetNewPath(pPath,FindFileData.cFileName,pSubstr); index++; }else if(FindFileData.nFileSizeLow!=0 && pSubstr==NULL){ no_of_files++; }if(FindFileData.nFileSizeLow==0 ){ no_of_folders++; } }while (FindNextFile(hFind, &FindFileData) != 0 ); for(i=0;i<index;i++){ WalkFolder(allpath[i],pSub_folders,pSubstr); } dwError = GetLastError(); FindClose(hFind); if (dwError != ERROR_NO_MORE_FILES) { printf ("FindNextFile error. Error is %u\n", dwError); } } char * GetNewPath(char* pPath,char *pFileName,char* pType) { char* path; if(pType==NULL){ path=(char*)calloc(strlen(pPath)+strlen(pFileName)+1,sizeof(char)); }else{ path=(char*)calloc(strlen(pPath)+strlen(pFileName)+strlen(pType)+1,sizeof(char)); } strcpy(path,pPath); path[strlen(path)-1]='\0'; strcat(path,pFileName); if(pType==NULL){ strcat(path,"\\*"); }else{ strcat(path,pType); } return path; } int FindMatch(char* pPath) { int i; i=strlen(pPath)-1; if(pPath[i]=='*'&& pPath[i-1]=='\\'){ return 1; } return 0; } char* GetSubstring(char* pPath) { char* substring; int i; int length; for(i=strlen(pPath)-1;i>0;i--){ if(pPath[i]=='\\') break; } length=strlen(pPath)+1-i; substring=(char*)calloc(length,sizeof(char)); strcpy(substring,(pPath+i)); return substring; } void RemoveSubString(char *pPath,char* pSubstr) { int len; len=strlen(pPath)-strlen(pSubstr)+4; pPath=(char*)realloc(pPath,(len)); //len=strlen(pPath); pPath[len-4]='\0'; strcat(pPath,"\\*."); } void PrintFileInfo(HANDLE hFind,WIN32_FIND_DATA *FindFileData,int *no_of_files) { do{ Display(FindFileData); *no_of_files++; }while(FindNextFile(hFind, FindFileData) != 0 ); } void PrintFileAttribute(DWORD fileAttribute) { int index; ///< holds the index of attribute array int flag; ///< holds the flag value ///< attribute array holds the file all attributes int attribute[12] = {FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_DEVICE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_TEMPORARY, FILE_ATTRIBUTE_SPARSE_FILE, FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_COMPRESSED, FILE_ATTRIBUTE_OFFLINE}; //Assign starting value zero to count index =0; //printf("\t"); //loop continue upto fileattribute greaterthan attribute[count] while (fileAttribute >=(unsigned long) attribute[index]) { //flag holds attribute value flag = fileAttribute & attribute[index++]; switch (flag) { //if the file attribute is readonly case FILE_ATTRIBUTE_READONLY: printf( "R "); break; //if the file attribute is hidden case FILE_ATTRIBUTE_HIDDEN: printf( "H "); break; //if the file attribute is system case FILE_ATTRIBUTE_SYSTEM: printf( "S "); break; //if the file attribute is archive case FILE_ATTRIBUTE_ARCHIVE: printf( "A "); break; //if the file attribute is device case FILE_ATTRIBUTE_DEVICE: printf( "D "); break; //if the file attribute is normal case FILE_ATTRIBUTE_NORMAL: printf( "N "); break; //if the file attribute is temporary case FILE_ATTRIBUTE_TEMPORARY: printf( "T "); break; //if the file attribute is sparse file case FILE_ATTRIBUTE_SPARSE_FILE: printf( "SF "); break; //if the file attribute is reparse point case FILE_ATTRIBUTE_REPARSE_POINT: printf( "RP "); break; //if the file attribute is compressed case FILE_ATTRIBUTE_COMPRESSED: printf( "C "); break; //if the file attribute is offline case FILE_ATTRIBUTE_OFFLINE: printf( "O "); break; } } }
when we use vc++ ,we write _getch instead of getch . this is because, The POSIX name for getch is deprecated. so we use the ISO C++ conformant name: _getch. if we use getch ,we get a warning this is removed with the help of using _getch
I required this assignment . Can you send me with some detail because whatever you posted that is not understandable As per told by johnson.reddy,
ya i have realised i have missed the comments. i will post the article back again with proper explanation.
Code: //Header Files #include "filelist.h" /** * main () this is used to receive path at the command line. * * @Param [in] argc contains the number of strings in a command prompt. * * @Param [in] *argv[] contains the address of the strings. * */ int main(int argc, char *argv[]) { char* DirSpec; // pointer to a character declaration. int traversal; //variable declaration. char* substring; // pointer to a character declaration. argv[1]="c:"; argv[2]="/s"; argc=2; printf ("Target directory is %s.\n", argv[1]); DirSpec=(char*)calloc ( strlen(argv[1])+1,sizeof(char)); //memory allocation for the path. strcpy(DirSpec,argv[1]); //copies the argv[1] to path. printf("Name \t\t\t\t Dir/Size \t Created \t Attributes"); if(strcmp(argv[2],"/s")==0){ traversal=INTERNALTRAVERSING; //sets the traversal type to internal. }else{ traversal=FIRSTLEVELTRAVERSING; //sets the traversal type to first level. } //checks if the path contains an extension. if(FindMatch(DirSpec)!=1){ if(GetFileAttributes(DirSpec)==FILE_ATTRIBUTE_DIRECTORY){ substring=NULL; strcat(DirSpec,"\\*"); }else{ substring=GetSubstring(DirSpec); //retrieves the extensio of the path in a substring. } }else{ substring=NULL; } WalkFolder(DirSpec,traversal,substring); //calls the walk folder with path,traversal type and extension. _getch(); free(DirSpec); //frees the memory allocated for path. return (0); } /** * Display(WIN32_FIND_DATA *pFindFileData) () is used to display the details of the file or folder. * * @Param [in] *pFindFileData contains the file data. * */ void Display(WIN32_FIND_DATA *pFindFileData) { LPSYSTEMTIME lpst; lpst=(LPSYSTEMTIME)calloc(1,sizeof(SYSTEMTIME)); //allocates memory for lpst. FileTimeToSystemTime(&pFindFileData->ftCreationTime,lpst); //converts the time to system time. if(pFindFileData->nFileSizeLow==0) printf ("\n %s \t\t\t\t <Dir>\t\t ", pFindFileData->cFileName); else printf("\n %s \t %d \t ",pFindFileData->cFileName,pFindFileData->nFileSizeLow); printf("%d/%d/%d %d:%d:%d \t ",lpst->wDay,lpst->wMonth,lpst->wYear,lpst->wHour,lpst->wMinute,lpst->wSecond); PrintFileAttribute(pFindFileData->dwFileAttributes); free(lpst); //frees the memory allocated for lpst. } /** * WalkFolder (char* pPath,BOOL pSub_folders,char* pSubstr)() used to insert an integer into the specified stack. * * @Param [in] pValue contains the value which is to be pushed into the buffer. * * @Return int 0 when pop fails else the element which was poped out. */ void WalkFolder (char* pPath,BOOL pSub_folders,char* pSubstr) { WIN32_FIND_DATA FindFileData; HANDLE hFind; //contains the handle returned by the path. DWORD dwError; //contains the last error occurred. char ** allpath; //pointer to the array which stores all new paths. int index=0; //contains the total count of paths stored. int i; //used for looping. static int no_of_files=0; //contains the number of files. static int no_of_folders=0; //contains the number of folders. printf("\n ................................................................."); printf("\n The display is for the path %s \n ", pPath); allpath=(char **)calloc(DEFAULTSIZE,sizeof(char*)); //allocates memory for allpath. hFind= INVALID_HANDLE_VALUE; //assigness invalid handle value to hFind. hFind = FindFirstFile(pPath, &FindFileData); //assigns the first file handle to hFind. if (hFind == INVALID_HANDLE_VALUE && pSub_folders!=INTERNALTRAVERSING ) { printf ("Invalid file handle. Error is %u\n", GetLastError()); } else if(hFind!= INVALID_HANDLE_VALUE && pSubstr !=NULL){ PrintFileInfo(hFind,&FindFileData,&no_of_files); } if(pSubstr !=NULL && pSub_folders==INTERNALTRAVERSING){ RemoveSubString(pPath,pSubstr); //calls RemoveSubString function to remove the extension from it. hFind = FindFirstFile(pPath, &FindFileData); //assigns the first file handle to hFind. } do{ if(pSubstr==NULL){ Display(&FindFileData); //calls the display function to print the file and folder details. } if(FindFileData.nFileSizeLow==0 && (strcmp(FindFileData.cFileName,".")!=0) && (strcmp(FindFileData.cFileName,"..")!=0)&& pSub_folders==INTERNALTRAVERSING){ if((index+1)%DEFAULTSIZE==0 && index>0){ allpath=(char **)realloc(allpath,(index+DEFAULTSIZE)); //reallocates memory. } allpath[index]=GetNewPath(pPath,FindFileData.cFileName,pSubstr); //retrieves the new path and stores it in allpath. index++; }else if(FindFileData.nFileSizeLow!=0 && pSubstr==NULL){ no_of_files++; //increments the number of files }if(FindFileData.nFileSizeLow==0 ){ no_of_folders++; //increments the number of folders. } }while (FindNextFile(hFind, &FindFileData) != 0 ); //works until next file exists. for(i=0;i<index;i++){ WalkFolder(allpath[i],pSub_folders,pSubstr); //calls back the walk folder with the new path. } dwError = GetLastError(); //stores the last error FindClose(hFind); //closes the file opened,whose handle is passed. if (dwError != ERROR_NO_MORE_FILES) { printf ("FindNextFile error. Error is %u\n", dwError); //prints the error message. } } /** * GetNewPath(char* pPath,char *pFileName,char* pType)() used to retrieve the path for internal traversing. * * @Param [in] pPath contains the path from which new path is to be retrieved. * * @Param [in] pFileName contains the file from which new path is to be retrieved. * * @Param [in] pType contains a substring ,if the path is of specific type,else NULL. * * @Return char* returns the new path. */ char * GetNewPath(char* pPath,char *pFileName,char* pType) { char* path; //contains the new path. if(pType==NULL){ path=(char*)calloc(strlen(pPath)+strlen(pFileName)+1,sizeof(char)); //memory allocation for path ,if there is no extension. }else{ path=(char*)calloc(strlen(pPath)+strlen(pFileName)+strlen(pType)+1,sizeof(char));//memory allocation for path ,if there is extension. } strcpy(path,pPath); //copies the previous sent path to path. path[strlen(path)-1]='\0'; //adds a '\0' at the end of the path. strcat(path,pFileName); //adds the filename to the path. if(pType==NULL){ strcat(path,"\\*"); //adds \* if there is no extension. }else{ strcat(path,pType); //adds the extension at the back of the path. } return path; //returns the path . } /** * FindMatch(char* pPath)() used to find aparticular match pattern in the string. * * @Param [in] pPath contains the path from which match is to be found. * * @Return int returns true if match is found,else false. */ int FindMatch(char* pPath) { int i; i=strlen(pPath)-1; //calculates the length of the path if(pPath[i]=='*'&& pPath[i-1]=='\\'){ //checks if the path contains \* return TRUE; //returns true if \* is found. } return FALSE; //returns false if \* not found. } /** * GetSubstring(char* pPath)() used to get the extension of the path as substring. * * @Param [in] pPath contains the path for which extension is to be found. * * @Return char* returns the substring. */ char* GetSubstring(char* pPath) { char* substring; //contains the substring i.e the extension. int i; //used for looping. int length; //contains the length for the extension. for(i=strlen(pPath)-1;i>0;i--){ if(pPath[i]=='\\') //checks for first \ from back and breaks. break; } length=strlen(pPath)+1-i; //calculates the length of the extension. substring=(char*)calloc(length,sizeof(char)); //allocates memory for the substring. strcpy(substring,(pPath+i)); //copies the extension to substring. return substring; //returns the extension. } /** * RemoveSubString(char *pPath,char* pSubstr)() used to remove the substring from the path. * * @Param [in] pPath contains the path for which extension is to be removed. * * @Param [in] pSubstr contains the extension which is to be removed. * */ void RemoveSubString(char *pPath,char* pSubstr) { int len; //contains the length of the path without extension. len=strlen(pPath)-strlen(pSubstr)+4; //calculates the new length. pPath=(char*)realloc(pPath,(len)); //reallocates memory for path. pPath[len-4]='\0'; //appends a '\0' to end the path. strcat(pPath,"\\*."); //adds a \. at then sn dof the path. } /** * PrintFileInfo(HANDLE hFind,WIN32_FIND_DATA *FindFileData,int *no_of_files)() used to print the file details. * * @Param [in] hFind contains the hanle of the file . * * @Param [in] FindFileData used to find the data about the file . * * @Param [in] *no_of_files contains the number of files . * */ void PrintFileInfo(HANDLE hFind,WIN32_FIND_DATA *FindFileData,int *no_of_files) { do{ Display(FindFileData); //calls the display function to print the file and folder details. *no_of_files++; //calculates the number of files. }while(FindNextFile(hFind, FindFileData) != 0 ); //works until no more files are left. } /** * PrintFileAttribute(DWORD fileAttribute)() used to print the attributes of the file. * * @Param [in] pFileattribute contains the attributes of the file. * */ void PrintFileAttribute(DWORD pFileattribute ) { int index; ///< holds the index of attribute array int flag; ///< holds the flag value ///< attribute array holds the file all attributes int attribute[12] = {FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_DEVICE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_TEMPORARY, FILE_ATTRIBUTE_SPARSE_FILE, FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_COMPRESSED, FILE_ATTRIBUTE_OFFLINE}; //Assign starting value zero to count index =0; //printf("\t"); //loop continue upto fileattribute greaterthan attribute[count] while (pFileattribute >=(unsigned long) attribute[index]) { //flag holds attribute value flag = pFileattribute & attribute[index++]; switch (flag) { //if the file attribute is readonly case FILE_ATTRIBUTE_READONLY: printf( "R "); break; //if the file attribute is hidden case FILE_ATTRIBUTE_HIDDEN: printf( "H "); break; //if the file attribute is system case FILE_ATTRIBUTE_SYSTEM: printf( "S "); break; //if the file attribute is archive case FILE_ATTRIBUTE_ARCHIVE: printf( "A "); break; //if the file attribute is device case FILE_ATTRIBUTE_DEVICE: printf( "D "); break; //if the file attribute is normal case FILE_ATTRIBUTE_NORMAL: printf( "N "); break; //if the file attribute is temporary case FILE_ATTRIBUTE_TEMPORARY: printf( "T "); break; //if the file attribute is sparse file case FILE_ATTRIBUTE_SPARSE_FILE: printf( "SF "); break; //if the file attribute is reparse point case FILE_ATTRIBUTE_REPARSE_POINT: printf( "RP "); break; //if the file attribute is compressed case FILE_ATTRIBUTE_COMPRESSED: printf( "C "); break; //if the file attribute is offline case FILE_ATTRIBUTE_OFFLINE: printf( "O "); break; } } }
the main function basically takes care of the arguments passed at the command line . it checks whether a /s is there or not if so it has to search all sub directories. it further checks whether there is specific listing like .pdf or not
the display function merely takes care of displaying the details of the retrieved file in a particular format
the work of the walk folder is to find in a particular directory all the reset paths to be traversed and when the matched file is found it walks through it if it is a directory else it displays the details if it is a file.