1.GitHub地址:https://github.com/YJG1997/wc
2.psp表格
PSP2.1表格
PSP2.1 |
PSP阶段 |
预估耗时 (分钟) |
实际耗时 (分钟) |
Planning |
计划 |
60 | 50 |
· Estimate |
· 估计这个任务需要多少时间 |
30 | 20 |
Development |
开发 |
60 | 90 |
· Analysis |
· 需求分析 (包括学习新技术) |
30 | 40 |
· Design Spec |
· 生成设计文档 |
30 | 20 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 | 20 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
20 | 20 |
· Design |
· 具体设计 |
90 | 90 |
· Coding |
· 具体编码 |
1200 | 1440 |
· Code Review |
· 代码复审 |
60 | 60 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
60 | 50 |
Reporting |
报告 |
120 | 100 |
· Test Report |
· 测试报告 |
60 | 90 |
· Size Measurement |
· 计算工作量 |
30 | 30 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
60 | 50 |
合计 |
1930 | 2170 |
3.解题思路
刚拿到题目时,看到题目的需求是对程序设计语言源文件统计字符数、单词数、行数,统计结果以指定格式输出到默认文件中时,第一反应时怎么判定和区分字符、单词,然后怎么去计算行数,用判定换行符来解决计算行数的问题是否可行,看到后面,有对字符和单词判定的说明,思路稍微就有点清晰了。因为对Java还不是很熟练,于是重新翻看了一遍《面向对象程序设计教程》。只是看书具体编码还有些困难,于是借助百度参考了一下别人的经验。
4.程序设计实现过程
首先完成基本功能需求,即完成统计字符数、单词数和行数的功能,此基本功能包含在baseC类中,在此类中用count的重载确定执行的操作,具体计数的方法charcount()、wordcount()、linecount()。然后用FileWrite新建一个result.txt文件,将结果输出到此文件中。
至于扩展功能,用allfile()方法实现递归处理目录下符合条件的文件,用complex()方法实现统计更复杂的数据(代码行/空行/注释行),用stop()方法实现停用词表,即统计文件单词总数时,不统计该表中的单词。
5.代码说明
代码分为三部分,wc.java 是 main class,baseC.java实现基本功能,extendedC.java实现扩展功能。
基本功能中实现字符计数的方法charcount():
public static void charcount(String thefile){ int charcount=0; String sfile=new String(thefile); File file=new File(sfile); if(file.exists()){ try{ FileInputStream fis=new FileInputStream(file); InputStreamReader isr=new InputStreamReader(fis,"UTF-8"); BufferedReader br=new BufferedReader(isr); String line=new String(""); StringBuffer sb=new StringBuffer(); while((line=br.readLine())!=null){ sb.append(line); charcount+=line.length(); } br.close(); isr.close(); fis.close(); } catch(FileNotFoundException e){ e.printStackTrace(); } catch(UnsupportedEncodingException e){ e.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } } try{ //打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件 FileWriter writer = new FileWriter("result.txt", true); char[] message=(thefile+", 字符数:"+charcount+"\r\n").toCharArray();//换行"\r\n"不是"\n" writer.write(message); writer.close(); } catch(IOException e){ System.out.println("File read/write Error"+e); } }
wordcount()、linecount()大体类似。
complex()方法统计代码行/空行/注释行:
static void complex(String myfile,String outfile)throws FileNotFoundException { if(outfile==null) outfile="result.txt"; String sfile=new String(myfile); File file=new File(sfile); // 记录注释行数 long annotationLine = 0; // 记录空白行数 long blankLine = 0; // 记录有效代码的行数 long codeLine = 0; //假注释 long notLine=0; if (file == null || !file.exists()) throw new FileNotFoundException(file + ",文件不存在!"); BufferedReader br = null; // 判断此行是否为注释行 boolean comment = false; int whiteLines = 0; int commentLines = 0; int normalLines = 0; try { br = new BufferedReader(new FileReader(file)); String line = ""; while ((line = br.readLine()) != null) { line = line.trim(); if (line.matches("^[//s&&[^//n]]*$")||line.equals("{")||line.equals("}")) { // 空行 :本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{” whiteLines++; } /* 本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释: * }//注释 */ else if (line.startsWith("/*") && !line.endsWith("*/")||((line.startsWith("{/*")||line.startsWith("}/*"))&&!line.endsWith("*/"))){ // 判断此行为"/*"开头的注释行 commentLines++; comment = true; } else if (comment == true && !line.endsWith("*/")&&!line.startsWith("*/")) { // 为多行注释中的一行(不是开头和结尾) notLine++; commentLines++; } else if (comment == true && (line.endsWith("*/")||line.startsWith("*/"))) { // 为多行注释的结束行 commentLines++; comment = false; } else if (line.startsWith("//")|| line.startsWith("}//")||line.startsWith("{//")|| ((line.startsWith("{/*") ||line.startsWith("}/*")||line.startsWith("/*")) && line.endsWith("*/"))) { // 单行注释行 commentLines++; } else { // 正常代码行 //System.out.println(line); normalLines++; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); br = null; } catch (IOException e) { e.printStackTrace(); } } try{ //打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件 FileWriter writer = new FileWriter(outfile, true); char[] message=(myfile+",代码行/空行/注释行:"+(normalLines+notLine)+"/"+whiteLines+"/"+(commentLines-notLine)+"\r\n").toCharArray();//换行"\r\n"不是"\n" writer.write(message); writer.close(); } catch(IOException e){ System.out.println("File read/write Error"+e); } } }
6.测试设计过程
白盒测试用例设计技术可分为逻辑覆盖和路径覆盖,逻辑覆盖又可分为以下几种,从弱到强:
语句覆盖(SC):设计足够多的测试用例,确保每条语句都被执行过。
判定覆盖(DC):设计足够多的测试用例,确保每个判定都分别取真值与假值。
条件覆盖(CC):设计足够多的测试用例,确保每个条件都分别取真值与假值。(一个判定里可能包含多个条件)
判定/条件覆盖(DCC):设计足够多的测试用例,确保每个判定和条件分别取真值和假值。
条件组合覆盖(CMC):设计足够多的测试用例,确保覆盖每个判定中的各个条件的所有组合情况。(只考虑同一个判定内的各条件组合情况)
路径覆盖:设计足够多的测试用例,确保每条路径都被执行。如果程序复杂,比如包含循环的情况,路径覆盖的测试用例数将会是个天文数字,无法实现。可以采用简化了的路径覆盖,即将循环看成是一个判定,只考虑循环被执行和未执行两种情况。
wc主类:
public class wc{ public static void main(String[] args) { int len=args.length; String one,two,three,four,five,six,seven,eight,night;//定义参数 if(len<=1) System.out.println("请按照格式输入"); else { if(len==2) { one=args[0]; two=args[1]; if(one.equals("-a")) try { //System.out.println("morrdate"); extendedC.complex(two,null); } catch (FileNotFoundException e) { e.printStackTrace(); } else if(one.equals("-l")||one.equals("-c")||one.equals("-w")) baseC.count(one, two); else System.out.println("无该操作"); } else if(len==3) { one=args[0];two=args[1];three=args[2]; if(three.endsWith(".c")){ if((one.equals("-l")||one.equals("-c")||one.equals("-w")&&(two.equals("-l")||two.equals("-c")||two.equals("-w"))))//需两功能处理文件 baseC.count(one, two, three); else if(one.equals("-s")&&(two.equals("-l")||two.equals("-c")||two.equals("-w")||two.equals("-a")))//递归处理文件(简单统计单词、字符或行)(处理代码行、注释行和空行) { String[] list={two,three}; extendedC.allfile(list); } else System.out.println("输入格式错误!"); } else if(three.endsWith(".txt")&&two.equals("-e")){//停用词表,单词数 extendedC.stop(one, three,null); } else System.out.println("输入格式错误!"); } else if(len==4){ one=args[0];two=args[1];three=args[2];four=args[3]; if(four.endsWith(".c")){ if((one.equals("-l")||one.endsWith("-c")||one.equals("-w"))&&(two.equals("-l")||two.equals("-c")||two.equals("-w")) &&(three.equals("-l")||three.equals("-c")||three.equals("-w")))//需三功能处理文件 baseC.count(one, two, three,four); else if(one.equals("-s")&&(two.equals("-l")||two.equals("-c")||two.equals("-w")) &&(three.equals("-l")||three.equals("-c")||three.equals("-w")))//递归处理文件(简单统计单词、字符或行) { String[] list={two,three,four}; extendedC.allfile(list); } else System.out.println("输入格式错误!"); } else if(two.endsWith(".c")&&three.equals("-o")) baseC.count(one, two,three,four); else System.out.println("请按照正确格式输入"); } else if(len==9){ one=args[0];two=args[1];three=args[2];four=args[3];five=args[4];six=args[5];seven=args[6];eight=args[7];night=args[8]; if(one.equals("-s")&&two.equals("-a")&&(three.equals("-l")||three.equals("-c")||three.equals("-w")) &&(four.equals("-l")||four.equals("-c")||four.equals("-w"))&&six.equals("-e")&&eight.equals("-o")) { String[] list={two,three,four,five,six,seven,eight,night}; extendedC.allfile(list); } else System.out.println("请按照格式输入"); } else System.out.println("请按照格式输入"); } } }
根据主类设计测试用例如下:
在命令行输入:
1.len<=1
wc.exe -c
2.len==2
wc.exe -a file.c
3.len==2
wc.exe -l file.c
4.len==2
wc.exe -n file.c //输出“无该操作”
5.len==3
wc.exe -l -c file.c
6.len==3
wc.exe -c -e *.txt //"*.txt"表示txt文件
7.len==3
wc.exe -s -a *.c
8.len==4
wc.exe -c -w -l file.c
9.len==4
wc.exe -s -l -c file.c
10.len==9
wc.exe -s -a –c -w *.c–e stop.txt –o –output.txt
参考链接:
http://www.cnblogs.com/xinz/p/7426280.html
http://www.cnblogs.com/jiel/p/7545780.html
原文地址:https://www.cnblogs.com/JinGangYao/p/8613406.html