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. WebSocket(1)---WebSocket介绍

    WebSocket介绍   一.为什么需要 WebSocket? 初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处? 答案很 ...

  2. 原生端与服务器通过sessionid实现session共享以及登录验证

    注:原生端与服务器建立连接时产生的sessionid会变,跟上一次的不一样,为了保证sessionid一样,所以第一次服务器需要把sessionid返回给原生端,下一次与服务端会话时,原生端需要把这个 ...

  3. Windows平台编译MySQL5.7源码

    https://blog.csdn.net/linjingke32/article/details/85111711

  4. mycat 从入门到放弃 (转)

    http://blog.csdn.net/u013235478/article/details/53178657   1.非分片字段查询 Mycat中的路由结果是通过分片字段和分片方法来确定的.例如下 ...

  5. 解读经典《C#高级编程》第七版 Page79-93.对象和类型.Chapter3

    前言 本篇我们继续讲解本章其余的部分:构造函数.只读字段.匿名类型.结构详解.部分类.静态类.Object类.扩展方法,等. 01 类 构造函数 构造函数是一种特殊的方法: 与类同名 没有返回值,甚至 ...

  6. 使用sublime text3编写vuejs项目需要安装的一些插件

    最近使用webstorm开发vuejs项目的时候经常出现卡顿的现象,感觉还是sublime text3比较轻巧便捷,但是使用sublime text3需要安装一些插件- 1. 让vue文件高亮: 安装 ...

  7. [转]PHP开发者必须了解的工具—Composer

    本文转自:https://blog.csdn.net/Zhihua_W/article/details/80345973 Composer是PHP 用来管理依赖(dependency)关系的工具.你可 ...

  8. vs 调试 iis中的网站

    打开网站,在vs中附加进程,选择w3wp.exe,如果不能下断点,设置一下pdb文件位置

  9. C#设计模式之九组合模式(Composite Pattern)【结构型】

    一.引言 今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达的意 ...

  10. Spring 与 SpringMVC (或许不完整)

    一.什么是Spring Spring是一个开源的控制反转和面向切面(AOP)的容器框架.它的主要目的是使现有技术更加易用,推荐编码最佳实现,从而简化企业的开发. 提:使用Spring的好处有以下几项: ...