wordcount小程序
wordcount小程序
(1)github网址
https://github.com/yuyuyu960818/count_txt_file
(2)PSP表
PSP2.1 |
PSP阶段 |
预估耗时 (分钟) |
实际耗时 (分钟) |
Planning |
计划 |
30 |
30 |
· Estimate |
· 估计这个任务需要多少时间 |
30 |
30 |
Development |
开发 |
390 |
690 |
· Analysis |
· 需求分析 (包括学习新技术) |
10 |
40 |
· Design Spec |
· 生成设计文档 |
10 |
10 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
10 |
10 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
10 |
10 |
· Design |
· 具体设计 |
10 |
30 |
· Coding |
· 具体编码 |
300 |
420 |
· Code Review |
· 代码复审 |
10 |
20 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
30 |
150 |
Reporting |
报告 |
100 |
190 |
· Test Report |
· 测试报告 |
60 |
150 |
· Size Measurement |
· 计算工作量 |
20 |
10 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
20 |
30 |
|
合计 |
520 |
880 |
(3)解题思路
1.采用对主函数传参的方式获取参数-l、-c等,然后判断使用程序哪个功能。
2.对于三个基础功能,用BufferedReader来读取文件的信息,然后根据读取到的文件信息来判断文件里面的字符数、单词数、行数。
3.对于三个进阶功能:
1)获取复杂行数据:读取每行,然后 读取到“” 为空行,若不为空行,再通过判断//和/* */在行中位置,来判断是否是注释行。若不是注释行和空行则为代码行
2)遍历目录下符合条件的文件:遍历目录下的文件,读取文件名,若后缀符合参数要求的进行预定的功能。
3)停用词表:读取停用词表文件,然后和读入的单词进行比对。
大致决定了怎么进行编写后,开始百度查找关于文件读取写入的操作,然后是关于主函数传参数的用法。
部分学习的参考资料:
[1]http://blog.csdn.net/nickwong_/article/details/51502969 java读取txt文件和写入txt文件
[2]http://blog.csdn.net/docuxu/article/details/73604038 java main方法传入参数
[3]http://blog.csdn.net/aa8568849/article/details/52670133 java获得指定目录下所有文件文件名
[4]https://www.cnblogs.com/guoziyi/p/5993085.html java中String相等问题
[5]https://www.cnblogs.com/zhangjinru123/p/7247789.html java项目生成jar包和exe程序
(4)程序实现过程
整个程序只有一个main class,在main class里面通过main函数调用各个类内函数实现软件的功能。
函数:
public static int countline(String pathname)//一个计算文件里面行数的函数
public static int countcharacter(String pathname)//一个计算文件里字符数的函数
public static int countword(String pathname,String stoppathname,int way)//一个计算文件里单词数的函数,包括了停词表操作
public static int[] complicatedline(String pathname)//y一个计算复杂行数的函数
public static void outputresult(int way,String outstr,String Infilename)//输出结果到文件中
public static void main(String[] args)//main函数
public static ArrayList<String> getFileList(File dir, List<File> list,int deep)//调用返回制定目录下所有文件
main函数通过传入的参数来决定调用哪一个函数进行计算操作,最后用outputresult将结果来输出到目标文件中。
(5)代码说明
if(!Needs)//如果不需要进行搜索整个文件夹,则只需要进行file.c文件的结果,否则要先查整个文件夹的文件。 { //判断进行什么计算,然后将要输出的结果添加到outstr末尾,便于之后的输出 if(Needc) { int charnum = countcharacter(args[countnum]); outstr = outstr + args[countnum] + ",字符数:" + charnum + " \r\n"; } if(Needw) { if(!Neede) { int wordnum = countword(args[countnum],args[countnum],1); outstr = outstr + args[countnum] + ",单词数:" + wordnum + "\r\n"; } else { int wordnum; if(Needo) wordnum = countword(args[countnum],args[args.length-3],2); else wordnum = countword(args[countnum],args[args.length-1],2); outstr = outstr + args[countnum] + ",单词数:" + wordnum + "\r\n"; } } if(Needl) { int linenum = countline(args[countnum]); outstr = outstr + args[countnum] + ",行数:" + linenum + " \r\n"; } if(Needa) { int clinenum[] = new int [4]; clinenum = complicatedline(args[countnum]); outstr = outstr + args[countnum] + ", 代码行/空行/注释行: " + clinenum[3] + "/" + clinenum[1] + "/" + clinenum[2] + " \r\n"; } //判断是否制定了输入的文件,没有指定的话输入进result.txt if(Needo) { outputresult(1,outstr,args[args.length-1]); } else { outputresult(2,outstr,strc); } }
这里是通过调用函数判断进行哪个功能的调用,然后调用相应的函数,每个函数的返回值为该函数调用的结果,最后利用outputresult函数将结果输出到指定文件中。
public static int countline(String pathname)//计算行数,挨个读取文件中行,读取到一行+1 { int line = 0; File file = new File(pathname); try { BufferedReader reader = new BufferedReader(new FileReader(file)); String tempString = null; while ((tempString = reader.readLine()) != null) { line++; } reader.close(); } catch (Exception e) { e.printStackTrace(); } return line; }
这里是关于计算行数的一个函数,传入文件名作为参数,然后利用BufferedReader类来读取文件,按行读取,读到一行行数加一。
同理,对于字符数、单词数等也是利用BufferedReader类读取,然后计数等。
public static void outputresult(int way,String outstr,String Infilename) { if(way==1) { try{ File outfile = new File(Infilename); outfile.createNewFile(); // 创建新文件 FileWriter fw = new FileWriter(outfile); BufferedWriter out = new BufferedWriter(fw); out.write(outstr); out.flush(); // 把缓存区内容压入文件 out.close(); // 最后记得关闭文件 } catch(Exception e) { } } else if(way==2) { try{ String outpathname = "result.txt"; File outfile = new File(outpathname); FileWriter fw = new FileWriter(outfile); BufferedWriter out = new BufferedWriter(fw); out.write(outstr); out.flush(); // 把缓存区内容压入文件 out.close(); // 最后记得关闭文件 } catch(Exception e) { } } }
这段代码作用为将结果输出到目标文件,利用BufferedWriter类来实现。
当指定了输出的文件时,若文件不存在则创建一个。
(6)测试设计
测试采用自己设计单元测试的方法,尽量覆盖所有的可执行语句。
在这里写了一个testmain.java的文件,在这个文件中调用main class的main函数,传入参数,达到和在CMD中进行运行wc.exe程序一样的效果,对于进行测试用的file.c等文件,测试应产生的正确结果已知,作为预期结果与实际结果进行对比。
设计的测试包括的文件有:源程序、测试程序、file.c、file2.c、stop.txt、output.txt、result.txt等文件,具体文件内容可见github内。
在线学习2.3节对判定的测试中指出“语句覆盖就是要保证设计的测试用例应至少覆盖函数中所有的可执行语句”,为此,我针对WordCount类中的各个计算数据的方法,使用语句覆盖指标设计测试用例,共产生10个测试用例。
测试用例:
(1)-c file.c
预期结果:
file.c,字符数:91
(2)-w file.c
预期结果:
file.c,单词数:18
(3)-l file.c
预期结果:
file.c,行数:9
(4)-a file.c
预期结果:
file.c, 代码行/空行/注释行: 6/1/2
(5)-l -a file.c
预期结果:
file.c,行数:9
file.c, 代码行/空行/注释行: 6/1/2
(6)-l -a file.c -o output.txt
预期结果:
file.c,行数:9
file.c, 代码行/空行/注释行: 6/1/2
(7)-w file.c -e stop.txt
预期结果:
file.c,单词数:17
(8)-c -l -w -a file.c -e stop.txt -o output.txt
预期结果:
file.c,字符数:91
file.c,单词数:17
file.c,行数:9
file.c, 代码行/空行/注释行: 6/1/2
(9)-s -l *.c -o output.txt
预期结果:
file.c,行数:9
file2.c,行数:2
(10)-c -l -w -a -s *.c -e stop.txt -o output.txt
预期结果:
file.c,字符数:91
file.c,单词数:17
file.c,行数:9
file.c, 代码行/空行/注释行: 6/1/2
file2.c,字符数:12
file2.c,单词数:2
file2.c,行数:2
file2.c, 代码行/空行/注释行: 2/0/0
一共10个测试用例,覆盖了所有可执行语句。
结果如下:
考虑后添加的测试用例,用于测试边界值和异常值:
(11)-c -s *.cpp -o outpu.txt
预期结果:output.txt里面内容为空
(12)-c -s .c -o output.txt
预期结果:命令行输出:输入参数错误
(13)-c -k file.c
预期结果:命令行输出:输入参数错误
(14)-c -s C:\Users\f\.c
预期结果:命令行输出:输出有关exception的内容
(7)参考资料
[1]http://blog.csdn.net/nickwong_/article/details/51502969 java读取txt文件和写入txt文件
[2]http://blog.csdn.net/docuxu/article/details/73604038 java main方法传入参数
[3]http://blog.csdn.net/aa8568849/article/details/52670133 java获得指定目录下所有文件文件名
[4]https://www.cnblogs.com/guoziyi/p/5993085.html java中String相等问题
[5]https://www.cnblogs.com/zhangjinru123/p/7247789.html java项目生成jar包和exe程序
[6]http://www.cnblogs.com/xinz/archive/2011/11/20/2255830.html 单元测试 & 回归测试