一,Github地址:https://github.com/mushan520/WC.git
二、PSP表格:
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 40 | 45 |
· Estimate | · 估计这个任务需要多少时间 | 40 | 45 |
Development | 开发 | 1240 | 1165 |
· Analysis | · 需求分析 | 60 | 70 |
· Design Spec | · 生成设计文档 | 50 | 50 |
· Design Review | · 设计复审 | 30 | 45 |
· Coding Standard | · 代码规范 | 30 | 30 |
· Design | · 具体设计 | 80 | 60 |
· Coding | · 具体编码 | 900 | 800 |
· Code Review | · 代码复审 | 30 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 80 |
Reporting | 报告 | 100 | 120 |
· Test Report | · 测试报告 | 30 | 50 |
· Size Measurement | · 计算工作量 | 30 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 40 | 40 |
合计 | 1380 | 1330 |
三、解题思路
WC项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
①基本功能列表
- -c [文件名] 返回文件的字符数
- -w [文件名] 返回文件词的数目
- -l [文件名] 返回文件的行数
②扩展功能列表
- -s 递归处理目录下符合条件的文件。
- -a 返回更复杂的数据(代码行 / 空行 / 注释行)。
阅读完项目的需求后,整个项目的流程主要就是接收具体的参数对指定的文件进行具体的操作。以下为解题思路:
main函数中:通过输入的命令来判断执行各个功能函数,将输入的命令传到count文件,用指令来判断需要执行的方法,文件路径作为参数。readLine读取数据并记录下来,拼接为一行,在使用正则表达式进行判断以此统计单词数;使用JAVA的readLine功能统计行数;把切割的词的长度统计字符;同理,使用正则表达式判断记录空行 / 注释行 / 代码行等。
四、设计实现过程
1.流程图
主函数调用count类来进行相关统计,用searchFile类来读取文件
2.项目目录
3.代码
package com.zwb.wc; import java.io.IOException; import java.util.Scanner; import java.io.File; import java.io.IOException; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class wc { public static void main(String[] args) throws IOException { while (true) { System.out.println("输入:-c 文件名 返回文件的字符数"); System.out.println("输入:-w 文件名 返回文件词的数目"); System.out.println("输入:-l 文件名 返回文件的行数"); System.out.println("输入:-a 文件名 返回文件的代码行 / 空行 / 注释行"); System.out.println("输入:-all 文件名 返回文件的字符数 /词数 /行数/注释行 /空行 /代码行 "); System.out.print("请输入命令:"); Scanner s = new Scanner(System.in); String m =s.nextLine(); String arr[]=m.split("\\s"); count.command(arr[1], arr[0]); } } } class searchFile { public static void foundFilePath(String path, String fileName) throws IOException { File file = new File(path); if (file.exists()) { File[] files = file.listFiles(); if (null == files || files.length == 0) { System.out.println("文件夹是空的!"); return; } else { for (File file2 : files) { if (file2.getName().contains(fileName)) { System.out.println("文件:" + file2.getAbsolutePath()); count.command(file2.getAbsolutePath(), "-all"); } } } } else { System.out.println("文件不存在!"); } } } class count{ static int cntCode = 0, cntNode = 0, cntSpace = 0; static boolean flagNode = false; public static void command(String path, String type) throws IOException { BufferedReader br = null; int countWord = 0; int countChar = 0; int countLine = 0; String str = ""; String strCount = ""; try { br = new BufferedReader(new FileReader(path)); }catch(Exception e) { System.out.println("输入的参数有误"); return; } while((str = br.readLine()) != null ){ // 计算行数 countLine++; // 计算特殊行的数目 if (type.equals("-a")||type.equals("-all")) { pattern(str); } str = str + " "; strCount += str; } for(int i=0;i~`$^+=|<>¥×]" , ""); boolean word = !s.equals(""); if(word) { countWord++; } } } if (type.equals("-w")||type.equals("-all")) { System.out.println("单词数:" + countWord); } if (type.equals("-c")||type.equals("-all")) { System.out.println("字符数:" + countChar); } if (type.equals("-l")||type.equals("-all")) { System.out.println("行数:" + countLine); } if (type.equals("-a")||type.equals("-all")) { System.out.println("注释行: " + cntNode); System.out.println("空行: " + cntSpace); System.out.println("代码行: " + cntCode); } System.out.println(); br.close(); cntNode = 0; cntSpace = 0; cntCode = 0; flagNode = false; } // 计算特殊行的数量 public static void pattern(String line) { String regxNodeBegin = "\\s*/\\*.*"; String regxNodeEnd = ".*\\*/\\s*"; String regx = "//.*"; String regxSpace = "\\s*"; if(line.matches(regxNodeBegin) && line.matches(regxNodeEnd)){ ++cntNode; return ; } if(line.matches(regxNodeBegin)){ ++cntNode; flagNode = true; } else if(line.matches(regxNodeEnd)){ ++cntNode; flagNode = false; } else if(line.matches(regxSpace)) ++cntSpace; else if(line.matches(regx)) ++cntNode; else if(flagNode) ++cntNode; else ++cntCode; } }
4.测试
①测试文件C:\Users\62750\Desktop\wcproject\TXT.txt
②测试结果
③代码覆盖
由于代码组织不太会,放在了同一个java源文件中,导致代码覆盖率低,仅为:7.4%
五、总结分析
由于对java的了解不深,在做这次个人项目的时候越发感觉到自己的不足。在本次项目开发中,重新学习了java基础,并且学习加深了正则表达式的使用。于此同时,第一次学会使用coverage插件进行代码覆盖率的统计。因为经验不足,导致代码覆盖率很低。在参考了其他同学的项目后,发现自己真的太菜了。必须好好加油。还有第一次学会使用GitHub,受益匪浅。按照软件工程的知道,使我了解了项目开发原来有怎么多学问,通过这次作业,自己主要是学会怎么从零开始一个程序的设计,对时间的安排,对功能的评估等等工程知识,我相信这次的项目作业对我以后的项目开发会有蛮大的帮助的。