软件工程第一次作业:wc.exe(java实现)

本文档详细记录了一个仿照经典wc.exe工具的程序设计与实现过程,该程序不仅统计字符数、单词数和行数,还增加了代码行、空行、注释行的统计功能,以及图形界面选项。

本项目源代码存放于GitHub地址:https://github.com/ridicuturing/wc.exe

准备用写一个wc.exe这样的一个软件,具体要求如下:

题目:

      wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:
程序处理用户需求的模式为:
wc.exe [parameter] [file_name]

基本功能列表: 3个小时 (2个小时)
wc.exe -c file.c //返回文件 file.c 的字符数
wc.exe -w file.c //返回文件 file.c 的词的数目
wc.exe -l file.c //返回文件 file.c 的行数

扩展功能:3.5小时
-s 递归处理目录下符合条件的文件。
-a 返回更复杂的数据(代码行 / 空行 / 注释行)。
空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
代码行:本行包括多于一个字符的代码。
注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:
} //注释
在这种情况下,这一行属于注释行。
[file_name]: 文件或目录名,可以处理一般通配符。

高级功能:1.5小时
-x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。
需求举例:
  wc.exe -s -a *.c

返回当前目录及子目录中所有*.c 文件的代码行数、空行数、注释行数。

解题思路:

      拿到题目后就想到了一个大概的结构,把没一个参数写成一个方法,他调用了哪些参数我就直接调用哪些方法。这样一细分下来,感觉这些参数的实现都不是很难。这些参数的功能实现起来也没多大难度。我打算把这个程序就封装在一个类就行了。

最开始的大致框架

public class WC{
    public void c();
    public void w();
    public void l();
    public void a();
    public void s();
}

先实现各个功能,最后才写main函数。main函数应该是很容易写的,到时我只要检测传来的参数有哪些,然后直接调用对应的方法就行了。

      本次程序还需要单元测试。上网学了一下Junit,在实现第一个方法后马上试了一下。当时真的“哇”了一下,这个东西也太有用了把。如果上个学期我用java写ftp服务端的时候用到了这个,就不会出现在答辩前修改的代码影响前面功能的导致错误。想来真是可惜。

      代码管理要求上传到github,这是我第一次正式开始使用github,之前学过一下git,还把自己做过的一个小东西放上去了,不过用起来又忘记怎么用了。最后决定直接用git的GUI,我觉得在没这方面的需求是,没必要太过的钻研git,还不如把时间用去钻研java。

实现过程的一些情况:

      1.在文件处理时,一开始是打算是打算一行一行弄的,可是这样实现起来有点麻烦。我想起python在文件处理时可以把文件直接提取出来,把文件内容直接作为一个字符串的处理,我觉得这种方法非常方便我的编码以及可以减少程序对文件读取的时间,大大提高我的效率。唯一的问题是这种方法是要求把文件内容全部放到内存来处理。这对一些小内存电脑出去大文件可能会出问题。我分析了一下需求,这次的软件是一个作业类型的,这个软件的目的并不是放到市场使用的产品,仅仅是我的一个作业,只要能在一般情况能运行起来就行了,所以我决定还是使用这种方法。

      2.判断单词数是我比较纠结的一个地方。在代码文件中,怎么才算作一个单词?最典型的就是这个"stdio.h",到底算一个单词吗?还有汉字又该怎么算?最后我决定不从语言学的角度去想什么是单词,而是用程序员的角度去考虑怎么才算一个的单词。最终我对这处单词的定义是:任何由连续的英文,数字以及下划线连续组成,且开头不为数字的字符串都算一个单词(正则表达式:[a-zA-Z_][\w]{0,}),而每一个汉字单独算一个单词(正则:[\u4e00-\u9fa5])

      3.在基本实现完之后,发现自己的框架对文件的处理有点问题。按照我的实现思路,运行一次命令,可能要读取多次文件,这可浪费了多几倍的时间.比如:

public void c(){
    String txt = getFile(filename);
}

一次命令中,每个参数都要单独读取一次文件。这是完全可以避免的。当我思考怎么改善的时候,发现几乎每个方法都要进行改动。我的解决方法:每次运行程序,直接把文件读取成字符串后存放在成员变量中。 普通方法很容易改,主要是递归读取文件那个方法卡了一下,而且还要改整个框架,或者说优化整个框架。这一点浪费了我挺多时间的,如果早一点考虑这个问题就好了。

运行情况

1482468-20180914191040222-1427813070.png

1482468-20180914191154820-1968158074.png
如果选择文件夹则相当于选择该文件夹下所有后缀为c的文件(加“-s”时会递归把里面文件夹里的文件也输出)

1482468-20180914191517186-2093373352.png

1482468-20180914191547208-1520235343.png

1482468-20180914191703094-1678883303.png

使用通配符时,默认以递归方式输出所有符合的文件。

项目小结:

1.最大的收获当然是发现了单元测试这个好东西,现在我写的小东西都容易出现后面的功能影响前面的功能,以后写大程序更加不用说了。在这次项目中,单元测试也的确帮我节省很多时间和精力,比如就在我优化框架,要修改所有方法时,它 就能很好的帮我查看是否出现错误。
2.写代码前对框架应该尽可能的想好,不然像这次后面优化一下就要大改,浪费了一个多小时。不过优化的那个点就算之前想多一个小时其实也未必会考虑到这点,只能说尽量考虑多一点吧。
3.在预计完成时间时,似乎都对程序低估了,实际很多都花了更多的时间。

PSP

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划4050
· Estimate· 估计这个任务需要多少时间4050
Development开发780810
· Analysis· 需求分析 (包括学习新技术)6050
· Design Spec· 生成设计文档
· Design Review· 设计复审 (和同事审核设计文档)
· Coding Standard· 代码规范 (为目前的开发制定合适的规范)3020
· Design· 具体设计3020
· Coding· 具体编码480540
· Code Review· 代码复审12060
· Test· 测试(自我测试,修改代码,提交修改)60120
Reporting报告90150
· Test Report· 测试报告3030
· Size Measurement· 计算工作量3030
· Postmortem & Process Improvement Plan· 事后总结, 并提出过程改进计划3090
合计9101010

转载于:https://www.cnblogs.com/ridi/p/9604119.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值