Java实现WC

Github项目地址:https://github.com/auxshaw/WC

项目要求

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

-基本功能列表:

wc.exe -c file.c //返回文件 file.c 的字符数(实现)

wc.exe -w file.c //返回文件 file.c 的词的数目 (实现)

wc.exe -l file.c //返回文件 file.c 的行数(实现)

-扩展功能:

s 递归处理目录下符合条件的文件。(未实现)

a 返回更复杂的数据(代码行 / 空行 / 注释行)(实现)

-高级功能:

-x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。(未实现)

需求举例:

 wc.exe -s -a .c

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

PSP

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

解题思路

本次项目要对文本文件的字符数,单词数和行数等进行统计,这可以使用Java中的字节流读取文件,字符流进行字符数的统计。之后,我用Pattern类和Matcher类进行模式匹配,使用正则表达式分辨出字符,单词,空行,注释行和代码行,用BufferedReader类中的readLine()统计行数。在实现功能时,统计字符数和行数比较简单,统计单词数就要麻烦许多,单词定义比较模糊,所以要对单词进行精确定义。我对单词的定义是:字母和数字组合在一起,中间没有空格则是一个英文单词,一个汉字则是一个词。最后,要统计空行数,注释行数和代码行数,空白行:整行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。注释行:存在//、/* /、/、*/的算作注释行。代码行:除了空白行和注释行之外的都是代码行。

设计实现

本次项目写了三个类,一个是运行程序的WC类,一个是检查命令和传递文件路径的Create类,最后是存放统计方法的Count类。

其中main()用Scanner类来接收命令的输入,并将命令传到create()里,用create()检查命令是否正确,同时匹配相应的命令调用相应的方法,并将文件路径传过去。在create()里,用Pattren类和Matcher类进行匹配,检查命令是否错误,用switch进行功能选择,调用Count类的方法。关系图如下:

代码说明

create()

检查命令是否正确,传递文件路径,匹配命令,调用方法

public void create(String command) throws IOException{
Count count=new Count();
//检查命令是否正确
Pattern Pa = Pattern.compile("^(\\-[cwla]\\s+){1,4}\\s*+\\S+$");
Matcher Ma = Pa.matcher(command);
if(!Ma.matches()) {
System.out.println("指令错误,请重新输入");
}
//文件路径
int index = command.lastIndexOf(" ");
String path = command.substring(index +1);
//匹配命令
Pattern pattern = Pattern.compile("\\-[cwla]");
Matcher Match = pattern.matcher(command);
while(Match.find()) {
switch (Match.group().replace("-", "")) {
case "c":
count.countchar(path);
break;
case "w":
count.countword(path);
break;
case "l":
count.countline(path);
break;
case "a":
count.countline3(path);
break;
}
}
}

countchar()

统计字符数,匹配非空白字符即可对显示的字符计数

//统计字符数
public void countchar(String path) throws IOException{
String str=null;
int countchar1=0;
BufferedReader br=new BufferedReader(new FileReader(path));
while((str=br.readLine())!=null){
Pattern p = Pattern.compile("\\S");
Matcher m = p.matcher(str);
while(m.find()) {
countchar1++;}
}
System.out.println("字符数:"+countchar1);
br.close();
}

countline()

统计行数,使用readLine()可以很容易得出行数

//统计行数
public void countline(String path) throws IOException{
String str=null;
int countline1=0;
BufferedReader br=new BufferedReader(new FileReader(path));
while((str=br.readLine())!=null){
countline1++;
}
System.out.println("行数:"+countline1);
br.close();
}

countword()

统计单词数,先匹配中文,统计中文词数,再用replaceAll()将非字母数字的字符替换成空格,按空格分割,将字符串存到数组中,则数组大小即为英文单词的数目,最后相加得到单词数

//统计英文单词数
public void countword(String path) throws IOException{
String str=null;
int countworde=0;
int countwordc=0;
int countword=0;
StringBuffer sbf = new StringBuffer();
BufferedReader br=new BufferedReader(new FileReader(path));
while((str=br.readLine())!=null){
//统计中文字数
Pattern pa = Pattern.compile("[\\u4e00-\\u9fa5]");
Matcher ma = pa.matcher(str);
while(ma.find()){
countwordc++;
}
//统计英文单词数
sbf.append(str);
String word=sbf.toString().replaceAll("[^a-zA-Z0-9]"," ");
String[] words=word.split("\\s+");
countworde=words.length;
}
countword=countwordc+countworde;
System.out.println("词的数目:"+countword);
br.close();
}

countline3()

统计空白行,代码行和注释行各行行数,用正则表达式和if语句去统计空白行,注释行和代码行

//统计空白行,代码行和注释行各行行数
public void countline3(String path) throws IOException{
String str=null;
int spacelines=0;
int codelines=0;
int notelines=0;
String notebegin="\\s*/\\*.*";
String noteend=".*\\*/\\s*";
String noteall="[^a-zA-Z0-9]*//.*";
String regxspace="\\s*\\S?\\s*";
boolean flag = false;
BufferedReader br=new BufferedReader(new FileReader(path));
while((str=br.readLine())!=null){
if (str.matches("\\s*/\\*.*\\*/\\s*")) {
notelines++;
continue;}
if (str.matches(notebegin)) {
notelines++;flag = true;}
else if (str.matches(noteend)) {
notelines++; flag = false;}
else if(str.matches(regxspace)){
spacelines++;}
else if (str.matches(noteall)) {
notelines++;}
else if (true == flag)
notelines++;
else codelines++;
}
System.out.println("空白行:"+spacelines);
System.out.println("注释行:"+notelines);
System.out.println("代码行:"+codelines);
br.close();
}

WC.java

读取输入的命令并将指令传到create()中

package wordcount;
import java.io.*;
import java.util.*; public class WC { public static void main(String[] args) throws IOException{
Create cr=new Create();
cr.tips();
Scanner scan = new Scanner(System.in);
String command=null;
while(scan.hasNextLine()) {
//读取控制台的命令
if (scan.hasNextLine()) {
command = scan.nextLine();}
cr.create(command);
}
scan.close();
} }

测试运行

文件已打包成wc.exe文件,可直接使用。

测试文件

一个空文件

只有一个字符

只有一个单词

只有一行

count.java

代码覆盖率

代码覆盖率:91.1%

项目小结

本次项目是第一次规划好设计流程,按部就班地完成。在这次项目中,我使用Java进行编程,复习了I/O流的使用,更加明白正则表达式的魅力所在,用正则表达式去实现本次项目的功能是非常方便的。而在这其中,我还有很多的不足,没有足够的能力去实现高级功能,代码中也有很多地方可以进行优化,我之后还会继续改进。此次也有许多收获,通过本次项目,我掌握了github,git的使用方法,知道了如何进行单元测试,明白了做项目之前做好规划是很有必要的。

个人项目:Java实现WC的更多相关文章

  1. 个人小项目——Java实现WC功能

    这个小项目用了两种方法解决了该功能的实现. 1.两种方法的功能和具体实现 代码可以成功运行,但是有一些情况考虑不完整,一种方法用了FileOutputStream输出流,为了解决空格无法统计问题,对文 ...

  2. 小白のjava实现wc.exe功能

    GitHub地址 项目完成情况 基本功能列表(已实现) wc.exe -c file.c     //返回文件 file.c 的字符数 wc.exe -w file.c    //返回文件 file. ...

  3. JAVA实现WC.exe功能

    项目要求 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功能,并能够快速地处理多个文件. 具体功能要求: 程序处理用户需求的模式为: wc.exe [paramet ...

  4. maven项目Java resources 上面有个红叉但是代码里面并没有什么报错

    maven项目Java resources 上面有个红叉但是代码里面并没有什么报错 解决办法: 1.通过: windows菜单  ->   show view/other 菜单  -> o ...

  5. 在IDEA中关于项目java版本问题

    在IDEA中关于项目java版本问题 当出现错误如:java无效的源发行版11或IDEA Error:java:Compliation failed:internal java complier er ...

  6. Eclipse导入项目java文件中文乱码

    感谢大佬:https://blog.csdn.net/ordinaryprogrammerc/article/details/83013710 本文链接:https://blog.csdn.net/o ...

  7. java实现WC项目

    个人项目:WC   wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数.单 ...

  8. 个人项目:实现wc.exe(Java)

    本项目Github地址:https://github.com/NNewBoy/wc 项目相关要求 基本功能:(已实现) -c 统计文件字符数 -w 统计文件词的数目 -l 统计文件行数 扩展功能:(已 ...

  9. 软件工程:java实现wc项目基本功能

    项目相关要求 项目地址:https://github.com/xiawork/wcwork 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功能,并能够快速地处理多个 ...

随机推荐

  1. [python]使用virtualenvWrapper

    什么是virtualenv virtualenv是python的环境管理工具,用于隔离python的运行环境.也就是说,一个项目可以有一个属于这个项目的运行环境,从而避免了因为依赖不同的模块而产生的错 ...

  2. TCP/IP 笔记 - TCP数据流和窗口管理

    TCP流量控制机制通过动态调整窗口大小来控制发送端的操作,确保路由器/接收端消息不会溢出. 交互式TCP连接 交互式TCP连接指该连接需要在客户端和服务器之间传输用户输入信息,如按键操作.短消息.操作 ...

  3. vue路由对不同界面进行传参及跳转的总结

    最近在做一个公众号的商城项目,主要用的VUE+MUI,其实今天这个点对于有过项目经验的前端工作者来说是最基础的,但也是必须要掌握的,今天小编主要是记录下传参和跳转的一些总结(仅供参考). 首先我们先上 ...

  4. 函数式编程之-拒绝空引用异常(Option类型)

    众多语言都会设计Option类型,例如Java 8和Swift都设计了Optional类型.其实这种类型早就出现在了函数式语言中,在OCaml和Scala中叫Option,在Haskell中叫Mayb ...

  5. iOS逆向开发(3):锁定APP的目标类与函数 | reveal | lldb | debugserver | 远程调试

    之前介绍了怎么获取APP的所有类的结构信息,这个有什么用呢?用处大了,比如以这一步为基础,下一步通过注入来做更多研究工作. 注入的最小单位是函数,实际上,编译执行的程序在编译后,类就不复存在了,留下来 ...

  6. Python机器学习笔记 使用sklearn做特征工程和数据挖掘

    特征处理是特征工程的核心部分,特征工程是数据分析中最耗时间和精力的一部分工作,它不像算法和模型那样式确定的步骤,更多的是工程上的经验和权衡,因此没有统一的方法,但是sklearn提供了较为完整的特征处 ...

  7. MyBatis源码解析(五)——DataSource数据源模块之非池型数据源

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6675633.html 1 回顾 上一篇中我解说了数据源接口DataSource与数据源工厂 ...

  8. bash内置命令的特殊性,后台任务的"本质"

    本文解释bash内置命令的特殊性.前台.后台任务的"本质",以及前.后台任务和bash进程.终端的关系.网上没类似的资料,所以都是自己的感悟和总结,如有错误,120分的期待盼请指正 ...

  9. 小型音乐播放器插件APlayer.js的简单使用例子

      本篇博客将会给出一个小型音乐播放器插件APlayer.js的使用例子.关于APlayer.js的具体介绍和Github地址,可以参考: https://github.com/MoePlayer/A ...

  10. Android Studio 基础控件使用

    TextView android:gravity="center" //文字对其方式 top bottom left right center android:textColor= ...