WordCount个人项目
1.GitHub地址:https://github.com/lyh27/WordCount
2、题目描述
Word Count
1. 实现一个简单而完整的软件工具(源程序特征统计程序)。
2. 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
3. 进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。
2.1 WC 项目要求
wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:
程序处理用户需求的模式为:
wc.exe [parameter] [file_name]
基本功能列表:
wc.exe -c file.c //返回文件 file.c 的字符数
wc.exe -w file.c //返回文件 file.c 的词的数目
wc.exe -l file.c //返回文件 file.c 的行数
扩展功能:
-s 递归处理目录下符合条件的文件。
-a 返回更复杂的数据(代码行 / 空行 / 注释行)。
空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
代码行:本行包括多于一个字符的代码。
注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:
} //注释
在这种情况下,这一行属于注释行。
3.解题思路
使用语言为JAVA,拿到题目要从电脑中获取文件,则需要利用到JAVA内部提供的BufferedReader来读取文件的内容,便于获取到所需要的行数,字符数,单词数等各种信息。然后通过用户的输入,来执行命令。本项目采取到了main函数中的args[]来输入代码。
4.设计实现过程
1.首先我利用了一个工具包Util,在里面分成了4个类,分别是CharLengthUtil,WordCountUtil,LineCountUtil,OtherLineCountUtil,里面分别实现了字符数的统计,单词的统计,行统计,以及包括空行,注释行,代码行的统计。
2.主函数main,设计用户的输入,调用方法。
5.具体的代码说明:
首先是CharLengthCountUtil
package wc.util; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class CharLengthUtil { //实现字符的统计 public static int CharLength(String filename){ int countChar=0; String sentence; BufferedReader br=null; try { br = new BufferedReader(new FileReader(filename)); while((sentence = br.readLine())!= null) //去除句子中的空格,以免加入到字符的统计 countChar += sentence.replace(" ","").length(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return countChar; } }
WordCountUtil
package wc.util; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class WordCountUtil { //实现单词的统计 public static int WordCount(String filename) { int wordCount=0; String sentence; BufferedReader br=null; try { br = new BufferedReader(new FileReader(filename)); while((sentence=br.readLine())!=null) { //将句子中的逗号,句号,问号,感叹号等替换成空格,方便统计单词个数 sentence =sentence.replace(",", " "); sentence =sentence.replace("."," "); sentence =sentence.replace("?"," "); sentence =sentence.replace("!"," "); wordCount += sentence.split(" ").length; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return wordCount; } }
LineCountUtil
package wc.util; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class LineCountUtil { //实现行的统计 public static int LineCount(String filename) { int line=0; BufferedReader br=null; try { br = new BufferedReader(new FileReader(filename)); while(br.readLine()!=null) line++; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return line; } }
OtherLineUtil
package wc.util; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class OtherLineCountUtil { //实现空行,代码行,注释行的统计 public static String OtherLineCount(String filename) { // TODO Auto-generated method stub int codeLine=0; int emptyLine=0; int noteLine=0; String sentence; BufferedReader br=null; String result; boolean inNoteLine=false; try { br = new BufferedReader(new FileReader(filename)); while((sentence=br.readLine())!=null){ //统计/*的注释行 if(inNoteLine==true) { noteLine++; if(sentence.endsWith("*/")||sentence.endsWith("*/}")) inNoteLine=false; continue; } if(sentence.startsWith("/*")||sentence.startsWith("{/*")) { noteLine++; if(!sentence.endsWith("*/")||!sentence.endsWith("*/}")) inNoteLine=true; continue; } //统计//的注释行 if(sentence.startsWith("//")||sentence.startsWith("{//")) { noteLine++; continue; } //空行的统计 if(sentence.equals("")||sentence.equals("{")||sentence.equals("}")||sentence.equals(" ")) { emptyLine++; continue; } //都不是的情况下统计代码行 codeLine++; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } result=Integer.toString(codeLine)+"/"+Integer.toString(emptyLine)+"/"+Integer.toString(noteLine); return result; } }
Main方法
package wc.main; import java.util.ArrayList; import java.util.List; import wc.util.CharLengthUtil; import wc.util.LineCountUtil; import wc.util.OtherLineCountUtil; import wc.util.WordCountUtil; public class WCmain { //基于main函数中的args的指令输入 public static void main(String[] args) { List<String> filenames =new ArrayList<>(); //利用集合存储文件 List<String> commands =new ArrayList<>(); //存储指令 for(int i=0;i<args.length;i++) { if(args[i].startsWith("-")) commands.add(args[i]); else { filenames.add(args[i]); } } for(int j=0;j<commands.size();) { switch(commands.get(j)) { case "-c" : System.out.println("字符数为:" + CharLengthUtil.CharLength(filenames.get(filenames.size()-1))); break; case "-w" : System.out.println("单词数为:" + WordCountUtil.WordCount(filenames.get(filenames.size()-1))); break; case "-l" : System.out.println("行数为:" + LineCountUtil.LineCount(filenames.get(filenames.size()-1))); break; case "-a" : System.out.println("代码行/空行/注释行:" + OtherLineCountUtil.OtherLineCount(filenames.get(filenames.size()-1))); break; case "-s" : for(int i=0;i<filenames.size();i++) { System.out.println(filenames.get(i)); System.out.println("字符数为:" + CharLengthUtil.CharLength(filenames.get(i))); System.out.println("单词数为:" + WordCountUtil.WordCount(filenames.get(i))); System.out.println("行数为:" + LineCountUtil.LineCount(filenames.get(i))); System.out.println("代码行/空行/注释行:" + OtherLineCountUtil.OtherLineCount(filenames.get(i))); } default: System.out.println("您的输入有误,请重新输入"); } break; } } }
6.测试结果
测试用例:
1.-c
2.-w
3.-l
4.-a
5.-s
7.PSP结果
|
Personal Software Process Stages | 预估耗时(分钟) |
|
||
Planning | 计划 | 20 | 15 | ||
Estimate | 估计这个任务需要多少时间 | 500 | 460 | ||
Development | 开发 | 450 | 460 | ||
Analysis | 需求分析 (包括学习新技术) | 100 | 120 | ||
Design Spec | 生成设计文档 | 30 | 35 | ||
Design Review | 设计复审 (和同事审核设计文档) | 10 | 5 | ||
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 0 | 0 | ||
Design | 具体设计 | 10 | 10 | ||
Coding | 具体编码 | 430 | 420 | ||
Code Review | 代码复审 | 60 | 50 | ||
Test | 测试(自我测试,修改代码,提交修改) | 20 | 15 | ||
Reporting | 报告 | 10 | 15 | ||
Test Report | 测试报告 | 20 | 15 | ||
Size Measurement | 计算工作量 | 10 | 5 | ||
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 10 | 15 | ||
Sum | 合计 | 560 | 585 |
8.项目总结
这不是一个完整的项目,代码质量不算高,这次使用了较少使用的JAVA语言,在开发过程中无法做到尽善尽美,很多东西都要学习很久才能动手,但这也进一步锻炼我JAVA的编程能力,项目中的规范仍然不够,且仍然存在bug,例如:对于空文件还未进行处理,还未给出图形化的界面,以及还没有指导用户输入,以及还未解决空格算入字符数,单词数还不够准确的问题,总体来说还不够熟练,不过这应该算我第一个大致的JAVA项目,接下来还需要继续学习提高,利用PSP也提高了我的规划能力,提高我的效率。对于JAVA还要学习东西很多,我还必须进一步地提高自我,不断学习,Swing编程未涉及,以至于还无法做出图形化界面,技术还差很多。
9.参考资料
java统计一个文件的字符数,单词数,行数:https://blog.csdn.net/ycy0706/article/details/45457311
java的io流操作中BufferedReader的作用:https://blog.csdn.net/qq_40207805/article/details/78367916
Java中main方法参数String[] args的使用:https://www.cnblogs.com/xy-hong/p/7197725.html
Java startsWith() 方法:https://www.runoob.com/java/java-string-startswith.html