软工作业No.1。Java实现WC.exe
网址:https://github.com/a249970271/WC
WC 项目要求
wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
扩展功能:
-s 递归处理目录下符合条件的文件。
-a 返回更复杂的数据(代码行 / 空行 / 注释行)。
空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
代码行:本行包括多于一个字符的代码。
注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:
} //注释
在这种情况下,这一行属于注释行。
遇到的困难及解决方法
- 困难描述
一开始的时候不知道该选什么语言来实现这个程序,学过C,java,刚接触python。C有点忘了,而且对java的面向对象编程会比较熟悉,比较喜欢,所以选定了java。然后刚开始动手就开始懵了,我要怎么计算字符数?怎么读取文件?不能用ASCII码大于小于来定的吗?怎么这里报错那里又报错?关闭什么流?为什么说我重复报错了?我要读取字节还是字符?拓展功能怎么写?要分包吗?类怎么分?写拓展功能的时候还写着写着电脑中毒了emmmm吓死死了。
- 做过哪些尝试,是否解决
我之前上课的java书给师弟了,还好我留了一本师兄给我的《疯狂java讲义》,里面对各种类各种引用以及用法说得非常详细。简单地在网上搜索了一下读取文件要怎么办,发现是要用到IO流的。于是我查了书,看了下,如果是要读取文件字符数的话,要用Reader,字节就要用到InputStream,又查了查,如果是字母,数字这些,多用inputstream来计算,于是就用这个来计算了。然后书上也讲得比较详细,比如File类的用法,访问文件和目录这个可以用到拓展功能-s中,String类的用法就在做拓展功能-a的时候提供了很大的方便。说是说用java,但是写到后面感觉哪里怪怪的,好像在把java当c一样,又没有分类又没有分包,我也不知道该怎么办,不过功能好歹是实现了。中间碰到一些没见过的报错时,会复制一下百度解决方法,比如重复关闭输入流这个,知道了是这个错误后再仔细看看自己代码是不是哪里循环写错了,还是“}”没用对。
对了,还有写拓展功能的时候,电脑中毒,开机后运行什么都奇慢,尤其是打码的时候,输完一行可能都要等个十几分钟来显示,心态差点就崩了。还好我,机智地,保存了代码后,关机,睡觉。第二天起来杀毒。现在没事啦,流畅多了吼吼!(还一时冲动买了内存条,希望山竹给点面子。。让我先收了货再下雨吧。。。
- 有何收获
收获就是,要多看书,多练习,多学多做,知道了怎么用好github,要好好运用百度或者google,然后对java又重拾了信心emmmm不过面对下一个作业还是很悬。。因为跟我组队的同学主C我主Java。。。
关键代码or设计说明
1 public static void getchars(String filename1) { 2 File file = new File(filename1); 3 if(!file.exists()) { 4 System.out.println("未找到目标文件。");//指定路径下的文件不存在则输出:未找到目标文件 5 }else { 6 try { 7 FileInputStream fis=(new FileInputStream(file)); 8 int temp=0; 9 while ((fis.read()) !=-1) { 10 temp=temp+1;//每读取一个字符temp+1 11 } 12 System.out.println("该文件的字符数:"+temp);//输出temp 13 fis.close();//关闭输入流 14 }catch (IOException ex) { 15 ex.printStackTrace();//捕获异常 16 } 17 } 18 }
- 计算字符数,写出这个后往下写就比较顺利了,感觉跟这个再加点东西就ok了
就一个个地读,读到一个就temp+1
public static void getlines(String filename1) { File file = new File(filename1); if(!file.exists()) { System.out.println("未找到目标文件。");//指定路径下的文件不存在则输出:未找到目标文件 }else { try { BufferedReader br = new BufferedReader(new FileReader(file)); int temp=0; while ((br.readLine())!= null) { temp=temp+1; } System.out.println("该文件的行数:"+temp);//文件不为空输出temp+1 br.close();//关闭输入流 }catch (IOException ex) { ex.printStackTrace(); } } }
- 了解了Buffered的用法后对它可以一次读一行的算法很感兴趣,感觉用来计算行数很方便又准确,于是把之前的改为这个
public static void getkonglines(String filename1) { int dl = 0, kl = 0, zl = 0; String t; File file = new File(filename1); if(!file.exists()) { System.out.println("未找到目标文件。");//指定路径下的文件不存在则输出:未找到目标文件 }else { try { BufferedReader br = new BufferedReader(new FileReader(file));//用bufferedreader可以一次读一行 while ((t = br.readLine())!= null) { if(t.trim().startsWith("//") == true || t.trim().startsWith("/*")==true ||t.trim().startsWith("}/*")==true || t.trim().startsWith("}//")==true){ zl=zl+1; }// 计算注释行数,去掉string首尾空格数 else if(t.trim().length()==0 || (t.trim().startsWith("}") == true && t.trim().length()==1)) { kl=kl+1; }// 计算注空行数,去掉string首尾空格数 else { dl=dl+1; }// 剩下的便是代码行 }br.close(); System.out.println("该文件的空行数:"+kl);//输出 System.out.println("该文件注释行数"+zl); System.out.println("该文件代码行数"+dl); }catch (IOException ex) { ex.printStackTrace(); } } }
- 拓展功能-a。
一开始以为可以一次读一行,一行中又可以一个字符一个字符地计算,后面报错发现只能用一个String类,然后查书发现String超好用,可以自动把首位空格忽略掉,还可以用以什么开头来判断这一行属于什么行,ok。
public static void file(String filess) { File file = new File (filess); String[] files = file.list();//列出File对象的所有子文件名和路径名,返回String数组 for(String f : files) { System.out.println("文件"+f+"的数据信息如下:"); getchars(filess+"/"+f); getwords(filess+"/"+f); getlines(filess+"/"+f); getkonglines(filess+"/"+f); } } }
- 拓展功能-s ,这个,实在是不知道怎么实现后面的条件限制,只写出了一个处理目录下所有的文件的这么一个方法了。
运行结果:
PSP
- 实现之前先在PSP中预估时间
- 实施后各个环节实际花费多少时间也请做记录
- 表中有一项: Estimate 指的“预估”这个活动,“预估时间”也是一项任务。
- 例如:我估计自己需要花30分钟来估算出整个项目需要多少时间完成,结果我花了20分钟估算出整个项目需要6个小时完成。Estimate这一项应该在“预估耗时”填写30分钟,实际耗时填写“20”分钟。
- 一级和二级活动的包含关系:
- Planning 这个一级活动包含了1个二级活动(Estimate)
- Development 这个一级活动包含了8个二级活动
- Reporting 这个一级活动包含了3个二级活动
- 大家在记录时间的时候, 只用记录二级活动, 然后把总数加了, 就是相应的一级活动的时间
PSP2.1 | Personal Software Process Stages | 预估耗时 | 实际耗时 |
---|---|---|---|
Planning | 计划 | 5min | 5min |
· Estimate | · 估计这个任务需要多少时间 | 5min | 5min |
Development | 开发 | 3d | 3d9h |
· Analysis | · 需求分析 (包括学习新技术) | 5h | 5h |
· Design Spec | · 生成设计文档 | 30min | 0 |
· Design Review | · 设计复审 (和同事审核设计文档) | 0 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 0 | 0 |
· Design | · 具体设计 | 5h | 3h |
· Coding | · 具体编码 | 2d | 3d |
· Code Review | · 代码复审 | 30min | 30min |
· Test | · 测试(自我测试,修改代码,提交修改) | 2h | 30min |
Reporting | 报告 | 70min | 70min |
· Test Report | · 测试报告 | 0 | 0 |
· Size Measurement | · 计算工作量 | 10min | 10min |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 1h | 1h |
合计 |
3d75min |
||
实际耗时 | 3d10h15min |
上面那个表格我不清楚该怎么弄。。实际耗时就加在那下面吧
记录自己的学习进度条(每周追加)
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 200 | 200 | 2d | 2d | 重新熟悉了java语言 |
---恢复内容结束---