软工作业1:wc.exe项目开发(java)
Github地址:https://github.com/Zzhaomin/learngit
项目相关要求 :
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 返回更复杂的数据(代码行 / 空行 / 注释行)。(实现)
空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
代码行:本行包括多于一个字符的代码。
注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:
} //注释
在这种情况下,这一行属于注释行。
[file_name]: 文件或目录名,可以处理一般通配符。
高级功能:
-x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。
需求举例:
wc.exe -s -a *.c
返回当前目录及子目录中所有*.c 文件的代码行数、空行数、注释行数。
遇到的困难及解决方法
- 困难描述
1. 一开始接触到题目时,就不知道如何输入命令和文件路径
2.对如何运用正则表达式去统计单词数这一方面不太懂
3.不懂得如何写测试单元
- 做过哪些尝试
1.百度搜索,然后看到了一些关于输入命令,空格,然后再输入文件路径,拆分成两部分使用的方法
2.收集一些关于正则表达式的学习资料,认真学习正则表达式
3.百度搜索如何写单元测试,以及问同学
- 是否解决
困难描述中的1、2两个困难都解决了,但困难描述3中如何写好单元测试还没有解决,写的单元测试有错
- 有何收获
1.重温了很多关于java的内容,例如输入输出流、switch等。
2.对正则表达式有一定的了解;懂得写一些比较简单的表达式
3.虽然单元测试没有写正确,但在尝试过程中也了解了单元测试的重要性。
设计实现过程
接收控制台输入,判断命令和文件路径是否正确,然后用switch语句读取命令,判断命令,调用各类方法。
代码说明
1.实现返回文件字符数目的功能
逐行读取文件,累加每一行的长度,直到文件被读取完。
//统计字符数目 public static int cCount() throws IOException { cCount = 0; File file = new File(File); FileInputStream fis = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); BufferedReader br = new BufferedReader(isr); String line = ""; while ((line = br.readLine()) != null) { cCount += line.length(); } return cCount; }
2.实现返回文件词数的功能
逐行读取文件,去除每一行起始和结束的空格,然后用split("\\s+").length统计词数
//统计词的数目
public static int wCount() throws IOException {
wCount = 0;
File file = new File(File);
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
line = line.trim();//删除起始和结尾的空格
wCount = sb.toString().split("\\s+").length;
}
return wCount;
}
3.实现返回文件总行数的功能
逐行读取文件,每读取一行,行数+1,直到读取完文件。
//统计行数总数
public static int lCount() throws IOException {
lCount = 0;
File file = new File(File);
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine())!= null) {
lCount = lCount +1;
}
return lCount;
}
4.实现统计代码行数、空白行数、注释行数的功能
逐行读取文件,根据判断line是否为空或长度是否小于等于1,为空或长度小于等于1空白行加1,判断行里是否连续出现//,若有注释行加1,其他情况代码行加1,一直读完整个文件
//统计代码行数、空白行数、注释行数
public static void moreLineCount() throws IOException {
codeLineCount = 0;
nullLineCount = 0;
noteLineCount = 0;
File file = new File(File);
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
if (line == "" || line.length() <= 1) {
nullLineCount = nullLineCount + 1;
continue;
}
int a = line.indexOf("/");//返回第一次出现的指定子字符串在此字符串中的索引。
int b = line.substring(a + 1).indexOf("/");
if (b == 0) {
noteLineCount++;
continue;
}
codeLineCount++;
}
}
5.main方法
判断输入的文件路径是否有误,没有就用switch调用方法得出相应的输出
public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根
System.out.print("wc.exe ");
Scanner s = new Scanner(System.in);
command = s.nextLine();
string = command.split(" ");
string1 = string[0];
File = string[1];
File file = new File(File);
if (file.exists()) {
switch(string1) {
case "-c" :
System.out.println("字符数目 :" + cCount());
break;
case "-w" :
System.out.println("词的数目 :" + wCount());
break;
case "-l" :
System.out.println("行数数目 : " + lCount());
break;
case "-a" :
moreLineCount();
System.out.println("代码行数 : " + codeLineCount);
System.out.println("空白行数 : " + nullLineCount);
System.out.println("注释行数 : " + noteLineCount);
break;
default : System.out.println("没有此命令");
}
}
else {
System.out.println("文件路径输入有误或者文件路径不存在");
}
}
测试运行
1.空白文件测试结果
测试结果正确
2.只有一个字符的文件测试结果
3.一个源文件的测试结果
PSP表格
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
20 |
20 |
· Estimate |
· 估计这个任务需要多少时间 |
20 |
15 |
Development |
开发 |
300 | 250 |
· Analysis |
· 需求分析 (包括学习新技术) |
300 | 350 |
· Design Spec |
· 生成设计文档 |
60 | 30 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
60 | 20 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
40 | 30 |
· Design |
· 具体设计 |
60 | 70 |
· Coding |
· 具体编码 |
300 | 400 |
· Code Review |
· 代码复审 |
100 | 120 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
200 | 300 |
Reporting |
报告 |
120 | 180 |
· Test Report |
· 测试报告 |
60 | 60 |
· Size Measurement |
· 计算工作量 |
60 | 70 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
30 | 40 |
合计 |
1730 | 1955 |
项目小结
1.对于java语言比较陌生,很多知识点都忘了,这次任务对于我来说有很大的难度,最终能把项目做出来还是很开心的
2.很多时候都是靠百度来解决问题,明确到搜索资料的重要性
3.对于Git、GitHub有了初步的了解。在初次建库上传代码时,出现了很多问题。一开始用命令行不成功,后来在eclispe里安装插件进行上传也是失败了,最后又尝试用命令行上传成功了
4.对于单元测试还是不懂。