Github地址
https://github.com/DolittleQZ/CountWord
PSP2.1表格
PSP2.1 | PSP 阶段 | 预估耗时 (分钟) | 实际耗时 (分钟) |
---|---|---|---|
Planning | 计划 | 15 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 20 | 20 |
Development | 开发 | 300 | 500 |
· Analysis | · 需求分析 (包括学习新技术) | 60 | 60 |
· Design Spec | · 生成设计文档 | 50 | 30 |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 40 | 100 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 240 | 300 |
· Code Review | · 代码复审 | 60 | 120 |
· Test | · 测试(自我测试,修改代码,提交修改) | 40 | 120 |
Reporting | 报告 | 60 | 100 |
· Test Report | · 测试报告 | 15 | 20 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 20 |
合计 |
解题思路
由于该项目要求使用java语言来实现,并且我上次使用java语言编程可能已经是一两年前,所以我感觉这个项目很难完成,但是这是老师布置的作业,没办法只能硬上了。首先题目要求的是在控制台输入命令来实现对指定文件(或文件夹内文件)单词数、字符数、行数以及代码行、空行和注释行数的统计。
首先在控制台获取用户输入的命令,解析命令,并将命令以空格为分界分段保存在一个字符串数组中;
然后遍历这个数组,针对对于不同的命令,我们可以调用相应的函数来一一实现这些功能。
程序设计实现过程
1.所以可以先写一个CountWords.java程序(即CountWords类),其中包含6个成员变量:
linecount //总行数
wordcount //单词数
charcount //字符数
nullLinecount //空行数
codeLinecount //代码行
noteLinecount //注释行
2.然后在类中添加成员函数
CountWD函数 //读取文件中字符数、单词数、行数以及代码行、空行和注释行数的统计
Writefile函数 //写入文件
PrintResult //在控制台程序中打印结果
PrintFile //将在控制台程序中打印的结果输入OutputFile文件中
traverseFolder2 //遍历目录下所有文件
3.接着写一个Test.java程序,进行控制台命令的处理
代码说明
Test.java主程序(部分):这部分是对命令的处理,获取参数并保存在sParameter字符串数组中,以及接下来调用CountWords.java中的方法。
1 Scanner scan = new Scanner(System.in); 2 String []sParameter= new String[10]; 3 for(int i=0;i!=sParameter.length;++i) 4 sParameter[i]=""; 5 int j=0; 6 String str=scan.next(); 7 if(str.equals("wc.exe")) { 8 str=scan.next(); 9 if(((str.equals("-c")||str.equals("-a"))||str.equals("-s"))||(str.equals("-w")||str.equals("-l"))){ 10 while(((str.equals("-c")||str.equals("-a"))||str.equals("-s"))||(str.equals("-w")||str.equals("-l"))) { 11 sParameter[j++] = str; 12 str = scan.next(); 13 } 14 String filename = Class.class.getClass().getResource("/").getPath(); 15 String filename1 = ""; 16 if(str.charAt(str.length()-5)=='*') { 17 if(str.charAt(0)=='*') 18 cw.traverseFolder2(Class.class.getClass().getResource("/").getPath(), sParameter); 19 else 20 { 21 str =str.substring(0, str.length()-5); 22 23 cw.traverseFolder2(str, sParameter); 24 } 25 } 26 else { 27 filename = filename + str; 28 filename1 = str; 29 cw = cw.CountWd(filename); 30 cw.PrintResult(sParameter, filename1); 31 } 32 str = scan.next(); 33 if(str.equals("-o")) { 34 sParameter[j++] = str; 35 str = scan.next(); 36 String filename2 = Class.class.getClass().getResource("/").getPath() + str; 37 cw.Writefile(sParameter, filename1,filename2); 38 }
CountWords.java:此类包含接下来要调用的所有方法。
首先是CountWD函数:读取文件中字符数、单词数、行数以及代码行、空行和注释行数的统计
1 //读取文件中字符数、单词数、行数以及代码行、空行和注释行数的统计 2 public CountWords CountWd(String sFilename) { 3 CountWords cw1 = new CountWords(0,0,0,0,0,0); 4 File file = new File(sFilename); 5 if(file.exists()) { 6 try { 7 FileInputStream fis = new FileInputStream(file); 8 InputStreamReader isr = new InputStreamReader(fis,"UTF-8"); 9 BufferedReader br = new BufferedReader(isr); 10 String line = ""; 11 StringBuffer sb = new StringBuffer(); 12 while ((line = br.readLine()) != null) { 13 int space = 0,xiegang = 0; 14 cw1.linecount++; 15 sb.append(line); 16 cw1.charcount += line.length(); 17 cw1.charcount++; 18 for(int i =0;i!=line.length();++i) { 19 if(line.charAt(i)=='/') 20 if(line.charAt(i+1)=='/') 21 { 22 xiegang = 2; 23 break; 24 } 25 if(line.charAt(i)!=' ') 26 ++space; 27 } 28 cw1.wordcount = br.toString().split("\40+|,+").length; 29 if(xiegang == 2 && space <=1) 30 cw1.noteLinecount++; 31 else if(space >= 2) 32 cw1.codeLinecount++; 33 else cw1.nullLinecount++; 34 } 35 cw1.wordcount = sb.toString().split("\40+|,+").length; 36 br.close(); 37 isr.close(); 38 fis.close(); 39 } catch (FileNotFoundException e) { 40 e.printStackTrace(); 41 } catch (UnsupportedEncodingException e) { 42 // TODO Auto-generated catch block 43 e.printStackTrace(); 44 } catch (IOException e) { 45 // TODO Auto-generated catch block 46 e.printStackTrace(); 47 } 48 } 49 return cw1; 50 } 51 }
Writefile:写入文件
1 //写入文件 2 public String Writefile(String []sParameter,String filename,String filename2) { 3 String str=""; 4 for (int i = 0; i < sParameter.length; i++) { 5 if (sParameter[i].equals("-l")) 6 str =str+ filename+",行数:"+String.valueOf(linecount)+"\r"; 7 else if (sParameter[i].equals("-w")) 8 str =str+ filename+",单词数:"+String.valueOf(wordcount)+"\r"; 9 else if (sParameter[i].equals("-c")) 10 str =str+ filename+",字符数:"+String.valueOf(charcount)+"\r"; 11 else if (sParameter[i].equals("-a")) 12 str =str+ filename+", 代码行/空行/注释行:"+String.valueOf(nullLinecount)+ 13 "/"+String.valueOf(codeLinecount)+ 14 "/"+String.valueOf(noteLinecount)+"\n"; 15 else if(sParameter[i].equals("-o")) { 16 PrintFile(str, filename2); 17 } 18 } 19 return str; 20 }
PrintResult:在控制台程序中打印结果
1 //在控制台程序中打印结果 2 public void PrintResult(String []sParameter,String filename) { 3 //String str=""; 4 for (int i = 0; i < sParameter.length; i++) { 5 if (sParameter[i].equals("-l")) { 6 // str =str+ filename+",行数:"+String.valueOf(linecount)+"\r"; 7 System.out.print(filename+",行数:"); 8 System.out.println(linecount); 9 } else if (sParameter[i].equals("-w")) { 10 //str =str+ filename+",单词数:"+String.valueOf(wordcount)+"\r"; 11 System.out.print(filename+",单词数:"); 12 System.out.println(wordcount); 13 } else if (sParameter[i].equals("-c")) { 14 //str =str+ filename+",字符数:"+String.valueOf(charcount)+"\r"; 15 System.out.print(filename+",字符数:"); 16 System.out.println(charcount); 17 } else if (sParameter[i].equals("-a")) { 18 //str =str+ filename+", 代码行/空行/注释行:"+String.valueOf(nullLinecount)+ 19 //"/"+String.valueOf(codeLinecount)+ 20 // "/"+String.valueOf(noteLinecount)+"\n"; 21 //atest.c, 代码行/空行/注释行: 10/3/9 22 System.out.print(filename+", 代码行/空行/注释行:"); 23 System.out.print(nullLinecount); 24 System.out.print("/"+codeLinecount); 25 System.out.println("/"+noteLinecount); 26 } 27 } 28 //return str; 29 }
PrintFile:将在控制台程序中打印的结果输入OutputFile文件中
1 //将在控制台程序中打印的结果输入OutputFile文件中 2 public void PrintFile(String content,String OutputFile) { 3 FileOutputStream fop = null; 4 File file; 5 try { 6 file = new File(OutputFile); 7 fop = new FileOutputStream(file); 8 // if file doesnt exists, then create it 9 if (!file.exists()) { 10 file.createNewFile(); 11 } 12 // get the content in bytes 13 14 byte[] contentInBytes = content.getBytes(); 15 16 fop.write(contentInBytes); 17 fop.flush(); 18 fop.close(); 19 20 } catch (IOException e) { 21 e.printStackTrace(); 22 } finally { 23 try { 24 if (fop != null) { 25 fop.close(); 26 } 27 } catch (IOException e) { 28 e.printStackTrace(); 29 } 30 } 31 }
traverseFolder2:遍历目录下所有文件
1 //遍历目录下所有文件 2 public void traverseFolder2(String path,String []sParameter) { 3 File file = new File(path); 4 if (file.exists()) { 5 File[] files = file.listFiles(); 6 if (files.length == 0) { 7 System.out.println("文件夹是空的!"); 8 return; 9 } else { 10 for (int i = 0; i < files.length; i++) { 11 if (files[i].isDirectory()) { 12 // System.out.println("文件夹:" + files[i].getAbsolutePath()); 13 traverseFolder2(files[i].getAbsolutePath(),sParameter); 14 } else { 15 //System.out.println("文件:" + files[i].getAbsolutePath()); 16 CountWords wc = new CountWords(0,0,0,0,0,0); 17 wc=wc.CountWd(files[i].getAbsolutePath()); 18 wc.PrintResult(sParameter,files[i].getAbsolutePath()); 19 } 20 } 21 } 22 } else { 23 System.out.println("文件不存在!"); 24 } 25 }
测试设计过程
首先在C:/Users/admin/Desktop/U201517028/abc/文件夹下创建文件,以便后续测试:
char.c
badca!@#$$%&^&*"':;|\/+_=-()
wordline.c
/*public void traverseFolder2(String path,String []sParameter) { */File file = new File(path);
// if (file.exists()) { File[] files = file.listFiles(); if (files.length == 0) {/* */ return;
}//ncvfkasfc
} else {
stoplist.txt
void file = new out
1.按照基本功能划分进行测试
1、 基本功能
(1)统计字符
wc.exe –c char.c
(2)统计单词和行数
wc.exe –w –l wordline.c
2、 扩展功能
(1) 统计代码行、空行、注释行
wc.exe –a wordline.c
(2) 停用词表
wc.exe –w stoptest.c –e stoplist.txt
(3) 文件夹遍历处理
wc.exe -s -a -w C:/Users/admin/Desktop/U201517028/abc/*.c
2.独立分支测试
主程序流程图如下:
有5个判定节点,故总共有6条路径,分别为:
Path1: 1,2,4,5,6,7,9,11,13,14 (经过所有判定节点)
Path2: 1,2,3,10,13,14 (在节点2处执行另一分支)
Path3: 1,2,4,10,13,14 (在节点4处执行另一分支)
Path4: 1,2,4,5,9,11,13,14 (在节点5处执行另一分支)
Path5: 1,2,4,5,6,8,9,11,13,14 (在节点6处执行另一分支)
Path6: 1,2,4,5,6,7.9.12.13.14 (在节点9处执行另一分支)
这些路径对应的用例为:
Path1: wc.exe -c -w -l -s C:/Users/admin/Desktop/U201517028/abc/*.c -o output.txt
Path2: cw.exe -c -w -l -s C:/Users/admin/Desktop/U201517028/abc/*.c -o output.txt
Path3: wc.exe -d -c -w -l -s C:/Users/admin/Desktop/U201517028/abc/*.c -o output.txt
Path4: wc.exe -c -w -l char.c -o output.txt
Path5: wc.exe -c -w -l -s *.c -o output.txt
Path6: wc.exe -c -w -l -s C:/Users/admin/Desktop/U201517028/abc/*.c
3.其他测试
没有该文件:wc.exe -a abc1.c
没有文件夹:wc.exe -a F:/bash/*.c
空文件测试:wc.exe -c -w -l -a a.c (假设a.c为一个空文件)
大文件测试:wc.exe -c -w -l -a b.c (假设b.c为一个大文件)
其他类型文件测试:wc.exe -c -w -l -a b.txt
查阅资料:
https://wenku.baidu.com/view/7cb4e4096fdb6f1aff00bed5b9f3f90f76c64df0.html
https://www.cnblogs.com/collectionne/p/6815924.html
http://blog.csdn.net/daxiang_zhang/article/details/2149896
http://blog.csdn.net/hpchenqi_16/article/details/48504111
http://blog.csdn.net/alex__0805/article/details/50895222
https://bbs.csdn.net/topics/390567815
https://www.cnblogs.com/zhaoyan001/p/6077492.html