以下代码用于统计指定目录下,指定后缀文件的个数及行数。参数为需要统计文件所在的目录路径及需要统计的文件后缀。目录路径及文件后缀都可以指定多个。如果不指定任何参数,那么默认统计当前目录下的.c文件的数目及所有.c文件中内容的总行数。 #include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <unistd.h> #define DIRECT 0 #define POST 1 typedef unsigned int uint; typedef struct _dircon { uint files; uint rows; const char *dir; const char *post; }dircon; typedef struct _paras { char type; const char *string; struct _paras *next; }paras; dircon strack[40]; int sp = 0; void pushs(uint files, uint rows,const char *dir, const char *post) { if(sp >= 10) { printf("strack overflow!/n"); return; } strack[sp].files = files; strack[sp].rows = rows; strack[sp].dir = dir; strack[sp].post = post; sp++; } void showStrack(void) { int n; printf("-------------------------------------------------------------/n"); for(n = 0; n < sp; n++) { printf("%d /"%s/" files, %d rows in directory /"%s/"/n", strack[n].files, strack[n].post,/ strack[n].rows, strack[n].dir); } printf("-------------------------------------------------------------/n"); } /************************************************* * check if "pcStr" contain "pcIn" * **************************************************/ int n_ifExist(const char *pcStr, const char *pcIn) { int nStr, nIn; for(nStr = 0; ; nStr++) { if(pcStr[nStr] == '/0') { return 0; } for(nIn = 0; ; nIn++) { if(pcIn[nIn] == '/0' && pcStr[nIn + nStr] == '/0') { return 1; } if(pcIn[nIn] != pcStr[nIn + nStr]) { break; } } } } /***************************************************** * statistic "type" type files in directory "dir" * ******************************************************/ void eachDir(const char *dir, const char *type) { DIR *pdir = NULL; struct dirent *pdDirent = NULL; char *pfname = NULL; FILE *pfile = NULL; uint rows; uint allrows; uint files; char ch; char pwdarr[200]; char *pwd; size_t len = 200; if((pdir = opendir(dir)) != NULL) { files = 0; allrows = 0; pwd = getcwd(pwdarr, len); //printf("current path is /"%s/"/n", pwd); chdir(dir); printf("/n++ Directory: /"%s/"/n", dir); while((pdDirent = readdir(pdir)) != NULL) { pfname = pdDirent->d_name; if(n_ifExist(pfname, type) && pdDirent->d_type == 8) { files++; if((pfile = fopen(pfname, "r")) != NULL) { rows = 0; while((ch = fgetc(pfile)) != EOF) { if(ch == '/n') { rows++; } } allrows += rows; printf("%-30s%-15d rows/n", pfname, rows); } else { fprintf(stderr, "can't open file %s/n", pfname); } } } if(files == 0) { printf("no /"%s/" files in directory /"%s/"/n", type, dir); } chdir(pwd); //pwd = getcwd(pwdarr, len); //printf("current path is /"%s/"/n", pwd); closedir(pdir); pushs(files, allrows, dir, type); //push all record to stack } else { fprintf(stderr, "directory %s can't open!/n", dir); } } /********************************** * main function, start here. * **********************************/ int main(int argc, char *argv[]) { DIR *pdir = NULL; paras *pstart = NULL; paras *pcurrent = NULL; pstart = (paras *)malloc(sizeof(paras)); pstart->next = NULL; pstart->string = NULL; pstart->type = -1; pcurrent = pstart; /********************************************* * Classification of the parameters * *********************************************/ int n; for(n = 1; n < argc; n++) { pcurrent->next = (paras *)malloc(sizeof(paras)); pcurrent = pcurrent->next; pcurrent->next = NULL; pcurrent->string = argv[n]; if((pdir = opendir(argv[n])) != NULL) { pcurrent->type = DIRECT; closedir(pdir); } else { pcurrent->type = POST; } } /****************************************************** * check if there is directory in the list * ******************************************************/ for(pcurrent = pstart; ;pcurrent = pcurrent->next) { if(pcurrent->type == DIRECT) { break; } else if(pcurrent->next == NULL) { pcurrent->next = (paras *)malloc(sizeof(paras)); pcurrent = pcurrent->next; pcurrent->type = DIRECT; pcurrent->string = "./"; pcurrent->next = NULL; break; } } /****************************************************** * check if there is post in the list * ******************************************************/ for(pcurrent = pstart; ;pcurrent = pcurrent->next) { if(pcurrent->type == POST) { break; } else if(pcurrent->next == NULL) { pcurrent->next = (paras *)malloc(sizeof(paras)); pcurrent = pcurrent->next; pcurrent->type = POST; pcurrent->string = ".c"; pcurrent->next = NULL; break; } } /********************************************************* * look over all the list to find direct and post * *********************************************************/ for(pcurrent = pstart->next; pcurrent != NULL; pcurrent = pcurrent->next) { //fprintf(stdout, "name: %s, type: %d/n", pcurrent->string, pcurrent->type); if(pcurrent->type == DIRECT) { paras *psearch = NULL; for(psearch = pstart->next; psearch != NULL; psearch = psearch->next) { if(psearch->type == POST) { eachDir(pcurrent->string, psearch->string); } } } } showStrack(); /************************************************************ * release all the memory that malloced * ************************************************************/ for(pcurrent = pstart; pcurrent != NULL; pcurrent = pcurrent->next) { free(pcurrent); } pstart = NULL; return 0; }