1.参考
http://www.cnblogs.com/ZCplayground/p/6275365.html
方法一样.用了下面这一行神秘代码
DIR *.* /B> LIST.TXT
可以发现DIR *.cpp/B> LIST.TXT 这样可以生成目录下cpp格式的文件记录
经过研究 我发现 把cpp去掉DIR *. /B> LIST.TXT这样就可以获取子目录的目录名
文章开头那个博客用了输出.bat文件并运行,在递归下出现各种问题,经过试验和改进,改为了直接运行指令,指令通过strcat拼接
1 char cmd[512];//拼出cmd命令2 strcpy(cmd, "DIR ");3 strcat(cmd, dir);4 strcat(cmd, "\\*.cpp /B>");5 strcat(cmd, dir);6 strcat(cmd, "\\cpplist.txt");7 system(cmd);8 //system("DIR e:\code\cpp\*.cpp /B>e:\code\cpp\list.txt")
2.考虑到目录类似于树 ,就用函数递归调用遍历整个子目录
在当前目录运行 system(“DIR*. /B> LIST.TXT”) 获取下级目录 然后递归调用 直到没有下级目录(递归调用在下面完整程序198行)
3.每次递归运行的函数都有当前目录的参数 利用system(“DIR *.cpp /B> LIST.TXT”)获取cpp文件列表(168行)
然后用循环 遍历打开所有cpp文件 统计行数
4.统计完成后 会在目录里遗留下很多 txt文件 应该清理掉(22行清除cpplist.txt 31行清除dirlist.txt)
for /r 当前目录 %i in(cpplist.txt) do del /q %i
5.把程序编译后 放在存放代码的文件夹内 运行后可以统计程序当前目录和子目录内所有cpp文件行数,包括空行和注释
6.完整程序
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #define _CRT_SECURE_NO_WARNINGS 6 7 /*2017年4月3日21:52:30 xuehu*/ 8 9 int cleanTxt(char *dir) 10 { 11 int ret = 0; 12 if (dir==NULL) 13 { 14 printf("ERR : %d row\n", __LINE__); 15 } 16 char cmd[512];//拼出cmd命令 17 strcpy(cmd, "for /r "); 18 strcat(cmd, dir); 19 strcat(cmd, " %i in ("); 20 strcat(cmd, "cpplist.txt"); 21 strcat(cmd, ") do del /q %i"); 22 system(cmd); 23 printf("cmd%s\n",cmd); 24 //for /r E:\code\cpp\Debug %i in(cpplist.txt) do del /q %i 25 //for /r E:\code\cpp\Debug %i in (cpplist.txt) do del /q %i //正确 26 strcpy(cmd, "for /r "); 27 strcat(cmd, dir); 28 strcat(cmd, " %i in ("); 29 strcat(cmd, "dirlist.txt"); 30 strcat(cmd, ") do del /q %i"); 31 system(cmd); 32 return ret; 33 } 34 35 int getCurrentDir(char* argv, char*currentDir) 36 { 37 int ret = 0; 38 39 if (currentDir == NULL) 40 { 41 printf("ERR: getCurrentDir()说: 你调用我的时候给我传空指针QAQ,我一用空指针就炸辣! : in %d row\n", __LINE__); 42 return -1; 43 } 44 int i = strlen(argv) - 1; //i移动到字符串尾 45 while (argv[i] != '\\') 46 { 47 i--; 48 } 49 if (i > 1) 50 { 51 strncpy(currentDir, argv, i);//复制前面的 52 } 53 //printf("%s\n",currentDir); 54 return ret; 55 } 56 57 58 int getCppRows(char *dir, int * count) 59 { 60 int ret = 0; 61 if (dir == NULL || count == NULL) 62 { 63 printf("QAQ: in getCppRows() : in %d row\n", __LINE__); 64 return -1; 65 } 66 int tmpcount = 0; 67 int filecnt = 0; 68 69 //1.system系统调用获取当前目录的cpp文件 70 char cmd[512];//拼出cmd命令 71 strcpy(cmd, "DIR "); 72 strcat(cmd, dir); 73 strcat(cmd, "\\*.cpp /B>"); 74 strcat(cmd, dir); 75 strcat(cmd, "\\cpplist.txt"); 76 system(cmd); 77 //system("DIR e:\code\cpp\*.cpp /B>e:\code\cpp\list.txt") 78 79 //2.遍历每个文件 获取行数 输出到屏幕 80 char txtpath[512]; 81 char cpppath[512]; 82 83 char listline[128]; 84 char cppline[1024]; 85 86 strcpy(txtpath, dir); 87 strcat(txtpath, "\\cpplist.txt"); 88 //printf("txtpath: %s\n",txtpath); 89 90 FILE *listfp, *cppfp; 91 listfp = fopen(txtpath, "r"); 92 //listfp = fopen("E:\\code\\cpp\\list.txt", "r"); 93 //listfp = fopen("list.txt", "r"); 94 if (listfp == NULL) 95 { 96 printf("ERR : 文件指针listfp==NULL in %d row\n", __LINE__); 97 return -1; 98 } 99 100 while (fgets(listline, 100, listfp))//获取list.txt里的内容101 {102 int len = strlen(listline);103 if (listline[len - 1] == '\n')104 listline[len - 1] = '\0';//去除换行符105 106 107 //1hineseCode.cpp108 strcpy(cpppath, dir);//拼出每个cpp的文件名109 strcat(cpppath, "\\");110 strcat(cpppath, listline);111 cppfp = fopen(cpppath, "r");//打开每个cpp文件112 113 /*~~~the beginning of counting lines of code~~~*/114 int cnt = 0;//每个cpp文件的行数115 116 if (cppline == NULL)//安全117 {118 printf("ERR : 文件指针listline==NULL in %d row\n", __LINE__);119 return -1;120 }121 122 while (fgets(cppline, 1024, cppfp))//open the correct file, according to the file name123 {124 tmpcount++;//统计行数125 cnt++;126 }127 filecnt++;128 printf("+%d行 \t[%d.cpp]--> %s.\n", cnt, filecnt, listline);//输出当前文件129 fclose(cppfp);//关文件指针130 }131 132 fclose(listfp);133 134 135 printf(" 目录-->%s ↑文件共有 : %d行. \n", dir, tmpcount);//输出当前文件136 printf("--------------------------------------\n");137 //3.然后加上总数 放到count里138 139 *count += tmpcount;140 return ret;141 }142 143 144 145 int scanDir(char* currentDir, int * count)146 {147 int ret = 0;148 if (currentDir == NULL || count == NULL)149 {150 printf("ERR in scanDir() : in %d row\n", __LINE__);151 return -1;152 }153 //0.先扫描当前目录154 ret = getCppRows(currentDir, count);155 if (ret != 0)156 {157 printf("QWQ: getCppRows() return %d: in %d row\n", ret,__LINE__);158 return -1;159 }160 161 //1.system运行获取目录162 char cmd[512];//拼出cmd命令163 strcpy(cmd, "DIR ");164 strcat(cmd, currentDir);165 strcat(cmd, "\\*. /B>");166 strcat(cmd, currentDir);167 strcat(cmd, "\\dirlist.txt");168 system(cmd);169 //2.如果目录为0个 return170 // 如果目录>0个 每个都递归执行171 char txtpath[512];172 char dirpath[512];173 174 char listline[128];175 176 strcpy(txtpath, currentDir);177 strcat(txtpath, "\\dirlist.txt");178 179 FILE *listfp;180 listfp = fopen(txtpath, "r");181 182 if (listfp == NULL)183 {184 printf("ERR : 文件指针listfp==NULL in %d row\n", __LINE__);185 return -1;186 }187 188 while (fgets(listline, 100, listfp))//获取list.txt里的内容189 {190 int len = strlen(listline);191 if (listline[len - 1] == '\n')192 listline[len - 1] = '\0';//去除换行符193 194 strcpy(dirpath, currentDir);//拼出每个文件夹名字195 strcat(dirpath, "\\");196 strcat(dirpath, listline);197 //递归调用函数198 scanDir(dirpath, count);199 }200 201 fclose(listfp);202 203 204 return ret;205 }206 207 int main(int argc, char *argv[])208 {209 int ret = 0;210 printf("xuehu写的用于统计cpp代码行数的小程序 \n");211 // 程序发布网址 : http://www.cnblogs.com/crosys/212 printf("-------------------------------------------------------\n");213 //printf("%s\n",argv[0]);214 //1.定义总行数 和其他变量215 int count = 0;216 217 //2.获取当前目录218 char currentDir[256] = { 0 };219 ret = getCurrentDir(argv[0], currentDir);220 if (ret != 0)221 {222 printf("ERR: func getCurrentDir() return %d\n", ret);223 return ret;224 }225 //3.当前目录传递给getNextDir()递归执行226 ret = scanDir(currentDir/*"E:\\code\\cpp"*/, &count);227 if (ret != 0)228 {229 printf("ERR: func scanDir() return %d\n", ret);230 return ret;231 }232 233 //4.递归结束后 输出总行数 结束程序234 printf("-------------------------------------------------------\n");235 printf("总行数为 -> %d 行.\n\n", count);236 237 printf("接下来清除残留文件 ");238 system("pause");239 //5.清除txt临时文件 240 ret = cleanTxt(currentDir);241 system("pause");242 return ret;243 244 }
编译器:visualstudio2017 34个警告(都是说strncpy strcat fopen这些不安全)
自己要先看得起自己,别人才会看得起你