#include#include #include #include #include #include int do_wc(char Filename[]);//读取每个文件中有多少行 多少单词 int foreach_dir(char dirname[]);//遍历每个子目录 int main(int argc, char *argv[]) { foreach_dir(argv[1]); return 0; } int foreach_dir(char dirname[]) { DIR *dir_ptr;//目录指针 struct dirent * entry_prt; dir_ptr = opendir(dirname);//打开通过命令行参数传进来的目录 if(dir_ptr == NULL) { perror("opendir errorn"); return -1; } char full_path_name[128]; struct stat buf;//使用stat结构体读取文件属性 保存到buf中 while((entry_prt = readdir(dir_ptr)) != NULL) //循环读取目录 { if((strcmp(entry_prt -> d_name, ".") && strcmp(entry_prt -> d_name, "..")) == 0) continue; strcpy(full_path_name, dirname); if(full_path_name[strlen(full_path_name) - 1] != '/') strcat(full_path_name, "/"); strcat(full_path_name, entry_prt -> d_name); if(stat(full_path_name, &buf) < 0)//返回关于文件的信息 { perror("stat errorn"); return -1; } if(S_ISDIR(buf.st_mode))//如果是一个子目录,循环读取目录 foreach_dir(full_path_name); else { if(strcmp(entry_prt -> d_name + strlen(entry_prt -> d_name) - 2, ".c") && //过滤C文件 strcmp(entry_prt -> d_name + strlen(entry_prt -> d_name) - 2, ".h") && //过滤C文件 strcmp(entry_prt -> d_name + strlen(entry_prt -> d_name) - 2, ".s"))//过滤C文件 continue; else //do_wc函数参数是绝对路径,而entry_prt->d_name是字符串,需要转换 do_wc(full_path_name);//读取目录下的文件名并传入do_wc函数 } } closedir(dir_ptr); return 0; } int do_wc(char Filename[]) { FILE *fp; static unsigned int lines = 0;//统计行数 static unsigned int words = 0;//统计单词数 static unsigned int files = 0;//统计文件数 int word_flag = 0;//用于表示一个单词统计完成 标记位 char ch; fp = fopen(Filename, "r"); if(fp == NULL) { perror("fopen"); return -1; } while((ch = fgetc(fp)) != EOF) { if(ch == 'n')//统计行数 lines++; if(ch == 'n' || ch == ' ' || ch == 't')//统计单词 { word_flag = 1; continue; } else { if(word_flag == 1) { words++; word_flag = 0; } } } fclose(fp); printf("%sn", Filename); printf("files: %dn", files++); printf("lines: %dn", lines); printf("words: %dn", words); return 0; }
运行结果如图:



