统计一个目录下cpp代码行数,子目录下也能统计

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了统计一个目录下cpp代码行数,子目录下也能统计相关的知识,希望对你有一定的参考价值。

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.cpp
108         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 name
123         {
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个 return
170     //   如果目录>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这些不安全)


以上是关于统计一个目录下cpp代码行数,子目录下也能统计的主要内容,如果未能解决你的问题,请参考以下文章

linux下shell统计文件目录下所有代码行数

统计代码行数

wc命令统计目录下所有文件行数

文件行数和代码行数统计

目录操作习题

cloc 统计代码行数工具