1、Github项目地址:https://github.com/Hare-Lucius/WordCount
2、 PSP2.1表格
PSP2.1 | PSP阶段 | 预估耗时 (分钟) | 实际耗时 (分钟) |
Planning | 计划 | 30 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 20 |
Development | 开发 | 570 | 580 |
· Analysis | · 需求分析 (包括学习新技术) | 30 | 20 |
· Design Spec | · 生成设计文档 | 30 | 30 |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 240 | 300 |
· Code Review | · 代码复审 | 30 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 90 |
Reporting | 报告 | 90 | 90 |
· Test Report | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 30 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
| 合计 | 690 | 690 |
3、解题思路:统计文件字符数、单词数、行数的功能较为基础,转化为对每一行的字符数和单词数的统计,并将行数累加即可。而对于字符数和单词数的统计可转化为对空注释格、逗号、水平制表符等分隔符的数量统计。同时,对每一行的单词进行存储,并与事先读入的停用词数组进行比对,每有相同者,则总单词数-1。在统计行数时, 分别对于空行和注释行进行统计,再用总行数减去二者即为代码行行数。最后考虑递归处理文件夹的情况,通过查阅资料可以找到递归查找指定文件夹下文件的函数,加以修改即可达到目的。
4、程序设计实现过程:对于给主函数传入的字符串数组进行分析,通过设置标识符判断后续应选择哪一种或哪几种统计方式。用一个函数对于输入文档进行分析,将字符数、单词数、行数的统计结果分别记录,再根据参数选择相应的输出结果和输出方式。另在主函数中对停用词表进行解析,将结果存入字符串数组,再与输入文档的单词一一比较(对于停用词表的文件中的内容,这里只考虑以空格隔开,不存在换行符等其他符号隔开的情况)。同时,在main函数对空行、注释行,代码行进行统计,此处需进行一些说明:凡处于段落中的行(例如空行或用"//"表示的注释行)均视为注释行,需求中未提及代码与注释同行出现的情况,此处直接将其处理为注释行。再用一个函数处理获取路径下所有c文件信息的功能,此处对相对路径和绝对路径进行了分别处理。下图为代码结构,函数依次是:主函数,读停用词表函数,处理相对路径函数,处理绝对路径函数,统计文件字符数、单词数、行数并输出的函数:
5、代码说明:
以“-w”为例,判断输入的参数中是否含有“-w”:
for(int ii=0;ii
对于单词数、字符数、行数的统计:
int cha=0,word=0,line=0,m=0; int v=0; Scanner in = new Scanner(new File(args[count])); while (in.hasNextLine()) { String str = in.nextLine(); for(int i=0;i=97&&b<=122)||(b>=65&&b<=90)) { v++; if((i==str.length()-1)) { word++; v=0; } } else { if(v>0) { word++; v=0; } } m=i+1; } cha+=m; line++; }
以"-o"为例,若输入参数中有"-o",则将统计结果写到输出文件的处理("-c"等输出方式较简单,故略):
if(of==1) { BufferedWriter bw = null; try { File file = new File(args[ocount+1]); if (!file.exists()) { file.createNewFile(); } FileWriter fileWriter =new FileWriter(file); fileWriter.write(""); fileWriter.flush(); fileWriter.close(); FileWriter fw = new FileWriter(file.getAbsoluteFile(),true); bw = new BufferedWriter(fw); //bw.write(args[count]+", 字符数:"+cha+"\r\n"+args[count]+", 单词数:"+word+"\r\n"+args[count]+", 行数:"+line+"\r\n"); if(cf==1) bw.write(args[count]+", 字符数:"+cha+"\r\n"); if(wf==1) bw.write(args[count]+", 单词数:"+word+"\r\n"); if(lf==1) bw.write(args[count]+", 行数:"+line+"\r\n"); bw.close(); } catch (IOException e) { e.printStackTrace(); } }
对代码行、空行、注释行的统计:
if(str.length()<2&&astart==0) sline++; if(str.contains("//")&&astart==0) aline++; if(str.contains("/*")&&astart==0) astart=1; if(str.contains("*/")&&astart==1) { astart=0; if(str.length()<3) { aline=aline+tmp+1; tmp=0; } else if(str.contains("/*")) { aline++; } else { aline=aline+tmp; tmp=0; } } line++; if(astart==1&&str.length()>0) tmp++;
对文件的递归处理(以相对路径为例)
public static void getFiles(File dir,String args[]){ if(dir.isDirectory()) { //判断是否目录, File[] files=dir.listFiles(new FilenameFilter() //定义过滤器,过滤文件类型为.java的文件 { public boolean accept(File dir,String name) { return name.endsWith(".c"); } }); for(int x=0;x
6、参考文献说明:
对于Java写入文档的参考网址:https://www.cnblogs.com/zhanglei93/p/5846592.html
对于Java字符串操作的参考网址:http://blog.csdn.net/fire1175/article/details/1690431
对于Java的main函数的参数的参考网址:http://blog.csdn.net/cherrybomb1111/article/details/71730114
对于Java递归处理文件的参考网址:http://blog.csdn.net/u012325167/article/details/50856515
7、测试说明:
测试过程对于每一项功能单独测试,再进行组合测试:
test.c中内容如下:
File write,name = new File(outputPath); writename.createNe|wFile(); Buffe,redWriter out = new BufferedWrit,er(new FileWriter(writename)); out.close();
test1.c中内容如下:
test() { File writename = new File(outputPath); writename.createNewFile(); codeLine */ BufferedWriter out = new BufferedWriter(new FileWriter(writename)); // note line out.write(outputBuffer); /* noteLine /* noteLine */ /* noteLine */ /* noteLine // noteLine */codeline out.flush(); out.close(); } // noteLine for(){ }/* noteLine */
test2中的内容如下:
public static void test(){ if(out == 3){ file = 100; System.out.println(file); } else if(out == 1){ file = files[0]; }}
stoplist中的内容如下:
out = file else void
说明:测试时,wc.exe位于与bin文件夹同一层级;前三个测试用例的结果以截图展示,后七个测试用例的结果以文件存储,可在github中查看。
a.wc.exe -c(测试字符数功能,但由于缺少文件名,应报错)
结果:(因为没有输入文件名)
b.wc.exe -c test.c(测试字符数功能)
结果:
c.wc.exe -c -w test.c(测试单词数功能)
结果:
d.wc.exe -c -w test.c -o output1.txt(测试字符数、单词数功能并输出至文本)
e.wc.exe -c -w -l test.c -o output2.txt(测试字符数、单词数、行数功能并输出至文本)
f.wc.exe -c -w -l -a test1.c -o output3.txt(测试字符数、单词数、行数功能,对行进行分类并输出至文本)
g.wc.exe -s -c -w -l -a *.c -o output4.txt(在缺省地址的情况下测试字符数、单词数、行数功能,对行进行分类并输出至文本)
h.wc.exe -s -c -w -l -a C:\Users\lby82\Desktop\test\*.c -o output5.txt(在绝对地址的情况下测试字符数、单词数、行数功能,对行进行分类并输出至文本)(test文件夹位于本机桌面,test文件夹下有一个test.c,还有一个文件夹test1,此子文件夹下含有test1.c,若脱离本机则结果应该不存在)
i.wc.exe -c -w -l -a test2.c -e stoplist.txt -o output6.txt(考虑停用词表,测试字符数、单词数、行数功能,对行进行分类并输出至文本)
j.wc.exe -s -c -w -l -a *.c -e stoplist.txt -o output7.txt(考虑停用词表,对当前目录下所有符合条件的文件进行测试字符数、单词数、行数功能,对行进行分类并输出至文本)
8、测试脚本
将所有测试用例编为bat脚本,运行bat脚本即可得出所有结果。
内容如下:
wc.exe -cwc.exe -c test.cwc.exe -c -w test.cwc.exe -c -w test.c -o output1.txtwc.exe -c -w -l test.c -o output2.txtwc.exe -c -w -l -a test1.c -o output3.txtwc.exe -s -c -w -l -a *.c -o output4.txtwc.exe -s -c -w -l -a C:\Users\lby82\Desktop\test\*.c -o output5.txtwc.exe -c -w -l -a test2.c -e stoplist.txt -o output6.txtwc.exe -s -c -w -l -a *.c -e stoplist.txt -o output7.txtpause