java实现空调车_基于Java实现wc工具

Github项目地址:https://github.com/Aliiiiiiiiiiiiiiiii/Handsome-boy

一.项目要求

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

实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。

具体功能要求:

程序处理用户需求的模式为:wc.exe [parameter]

[file_name]

基本功能列表:

wc.exe -cfile.c     //返回文件

file.c 的字符数

wc.exe -w

file.c    //返回文件

file.c 的词的数目

wc.exe -lfile.c      //返回文件

file.c 的行数

扩展功能:

-s   递归处理目录下符合条件的文件。

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

空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。

代码行:本行包括多于一个字符的代码。

注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:

} //注释

在这种情况下,这一行属于注释行。

[file_name]: 文件或目录名,可以处理一般通配符。

高级功能:

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

二.PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

120

90

· Estimate

· 估计这个任务需要多少时间

30

60

Development

开发

1440

1440

· Analysis

· 需求分析 (包括学习新技术)

120

120

· Design Spec

· 生成设计文档

30

50

· Design Review

· 设计复审 (和同事审核设计文档)

20

30

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

10

20

· Design

· 具体设计

60

90

· Coding

· 具体编码

50

100

· Code Review

· 代码复审

600

780

· Test

· 测试(自我测试,修改代码,提交修改)

300

250

Reporting

报告

150

150

· Test Report

· 测试报告

60

90

· Size Measurement

· 计算工作量

5

10

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

20

20

合计

1305

1620

三.解题思路

刚拿到题目的时候我并没有想到使用正则表达式去做匹配功能,后来跟同学讨论才知道的,看到对文件的操作就自然想到了学过的Java的输入输出流,对文件的操作也是比较了解的,所以选择了使用java去实现wc功能,至于这么多功能,我选择分模块去写代码,一个类实现一个功能,然后写一个main函数利用switch对用户输入的操作指令进行各项功能的实现,或许会有一些代码重复,但是思路直接,实现起来思路会清晰。统计字符使用正则表达式很容易就实现了,统计单词利用Pattern的split()方法把[^a-zA-Z]的分隔开,利用String[]存储再统计,行的统计就直接读一行就LineCount++。至于图形化界面,之前有学过相关的知识,所以是实现起来比较快,主要是输出文件的内容以及-c,-w,-l的实现。

四.设计实现过程

通过用户的输入而进入不同的功能模块,每个功能为一个类,通过while循环包含着switch语句进行可重复的操作

391bd93de1f62fb31a93f918e51f41e4.png

五.代码说明

主函数代码

packagewc;importjava.io.IOException;importjava.util.Scanner;public classStart {public static void main(String[] args) throwsIOException {//TODO 自动生成的方法存根

System.out.println("Welcome to wc.exe!\n");

System.out.println("----------指令参考-----------");

System.out.println("wc.exe -c 返回文件的字符数");

System.out.println("wc.exe -w 返回文件的单词数");

System.out.println("wc.exe -l 返回文件的行数");

System.out.println("wc.exe -s 递归处理目录下符合条件的文件");

System.out.println("wc.exe -a 返回代码行 / 空行 / 注释行");

System.out.println("wc.exe -x 显示图形界面");

System.out.println("wc.exe -exit 退出");

System.out.println("-------------------------------------\n");while(true) {

System.out.print("请输入指令: wc.exe -");

Scanner s=newScanner(System.in);

String in=s.nextLine();switch(in) { //输入不同的指令打开不同的类,实现不同的功能

case "c":

CharCount cc=newCharCount();break;case "w":

WordCount wc=newWordCount();break;case "l":

LineCount lc=newLineCount();break;case "s":

SCount sc=newSCount();break;case "a":

ACount ac=newACount();break;case "x":

HighLevel hl=newHighLevel();break;case "exit":

System.out.println("Good Bye!");

System.exit(0);default:

System.out.println("请输入正确的命令");

}

}

}

}

CharChout    字符统计

packagewc;importjava.io.BufferedReader;importjava.io.FileReader;importjava.io.IOException;importjava.util.Scanner;importjava.util.regex.Matcher;importjava.util.regex.Pattern;public classCharCount {

String REGEX="\\S"; //非空白字符

CharCount()throwsIOException{

Pattern p=Pattern.compile(REGEX); //利用正则表达式Pattern类以及Matcher类

System.out.println("请输入文件的绝对路径:");

System.out.print("wc.exe -c ");

Scanner inc=newScanner(System.in);

String path=inc.nextLine();

BufferedReader fis=new BufferedReader(newFileReader(path));

String s;int charcount=0;while((s=fis.readLine())!=null) {

Matcher m=p.matcher(s); //对正则表达式进行模式匹配

while(m.find())

charcount++;

}

System.out.println("该文件有"+charcount+"个字符\n\n");

fis.close();

}

}

WordCount  单词统计

public classWordCount {

String REGEX="[^a-zA-Z]";

WordCount()throwsIOException{

Pattern p=Pattern.compile(REGEX);

System.out.println("请输入文件的绝对路径:");

System.out.print("wc.exe -w ");

Scanner inw=newScanner(System.in);

String path=inw.nextLine();

BufferedReader fis=new BufferedReader(newFileReader(path));

String s;int wordcount=0;while((s=fis.readLine())!=null) {if(s.isEmpty()==false) { //要不是一行空行才进行下面的操作,不然要是有空行的话结果不对

String[] letter=p.split(s);for(String word : letter)

wordcount++;

}

}

System.out.println("该文件有"+wordcount+"个单词\n\n");

fis.close();

}

}

LineCount   行数统计

public classLineCount {

LineCount()throwsIOException{

System.out.println("请输入文件的绝对路径");

System.out.print("wc.exe -l ");

Scanner inl=newScanner(System.in);

String path=inl.nextLine();

BufferedReader fis=new BufferedReader(newFileReader(path));

String s;int linecount=0;while((s=fis.readLine())!=null) { //直接读到一行就+1

linecount++;

}

System.out.println("该文件有"+linecount+"行\n\n");

fis.close();

}

}

Scount     递归处理目录下符合条件的文件

public classSCount {

SCount()throwsIOException{

System.out.print("请输入要执行的操作:wc.exe -s -");

Scanner control=newScanner(System.in);

String ct=control.nextLine();

System.out.print("请输入要递归处理的目录路径:");

Scanner in=newScanner(System.in);

String path=in.nextLine();

System.out.print("请输入要递归处理的文件类型:wc.exe -s -"+ct+" *.");

Scanner style=newScanner(System.in);

String st=style.nextLine();

File file=newFile(path);

String[] name=file.list();

String s;int count=0;switch(ct) {case "c":

Pattern cp=Pattern.compile("\\S");for(String n:name) {if(n.matches("\\S+."+st)) { //找出目录下符合文件后缀的文件

BufferedReader fis=new BufferedReader(new FileReader(path+"\\"+n));while((s=fis.readLine())!=null) { //这里的操作跟前面的模块一样

Matcher m=cp.matcher(s);while(m.find())

count++;

}

System.out.println(n+" 中有"+count+"个字符");

count=0;

fis.close();

}

}break;case "w":

Pattern wp=Pattern.compile("[^a-zA-Z]");for(String n:name) {if(n.matches("\\S+."+st)) {

BufferedReader fis=new BufferedReader(new FileReader(path+"\\"+n));while((s=fis.readLine())!=null) {if(s.isEmpty()==false) {

String[] letter=wp.split(s);for(String word : letter)

count++;

}

}

System.out.println(n+" 中有"+count+"个单词");

count=0;

fis.close();

}

}break;case "l":for(String n:name) {if(n.matches("\\S+."+st)) {

BufferedReader fis=new BufferedReader(new FileReader(path+"\\"+n));while((s=fis.readLine())!=null) {

count++;

}

System.out.println(n+" 中有"+count+"行");

count=0;

fis.close();

}

}break;case "a":

}

}

}

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

public classACount {int total=0;int EmptyLine=0;int DescribeLine=0;int CodeLine=0;int tag=0; //设置一个标志,要tag=0,证明这一行还没扫描到“/*”,tag=1说明已经扫到了

ACount() throwsIOException{

Pattern p1=Pattern.compile("//");

Pattern p2=Pattern.compile("//*");

Pattern p3=Pattern.compile("/*/");

System.out.println("请输入文件的绝对路径:");

System.out.print("wc.exe -a ");

Scanner ina=newScanner(System.in);

String path=ina.nextLine();

BufferedReader fis=new BufferedReader(newFileReader(path));

String s;while((s=fis.readLine())!=null) {

total++;if(tag==0) { //根据tag的值进行不同的操作

Matcher m1=p1.matcher(s);

Matcher m2=p2.matcher(s);if(s.isEmpty()||(s.startsWith("{")&&s.endsWith("{"))) //只有tag=0时才计算空行,要是在多行注释里面出现的空行算入注释行而不算空行

EmptyLine++;else if(m1.find())

DescribeLine++;else if(m2.find()) {

DescribeLine++;

tag=1;

}

}else{

DescribeLine++;

Matcher m3=p3.matcher(s);if(m3.find()) //当匹配到“*/”的时候,说明多行注释结束,把tag置为0

tag=0;

}

}

CodeLine=total-DescribeLine-EmptyLine;

System.out.println("该文件有"+EmptyLine+"行空行");

System.out.println("该文件有"+DescribeLine+"行注释行");

System.out.println("该文件有"+CodeLine+"行代码行\n\n");

fis.close();

}

}

- x 显示图形界面的代码不在这里分析了,详细见Github源码

六.测试运行

0d53bdddf12cddc5e63d0d0c68f3bcfe.png

947dacd3ade723de72987bd84690e7aa.png

1e5654df0b6a1e914793fcd0574d5078.png

64540396de6c1f0d6ad743a38f0fa683.png

d944f048926657bb82f5724cee1332ae.png

七.项目小结

对于SCount以及ACount这两个类的语言逻辑,我出bug很多次了,总会存在一些小问题,后来发现自己的逻辑不够严谨,导致了运行结果的错误,而且整个程序还存在着或多或少的问题,有一些解决方法是我在上下学路上时候想到的,或许不是什么好的方法,但是这是我自己思考得出的方法,觉得通过这个项目的编程,我收获了不少,尽管最后做出来的程序有不足,但是通过自己思考和努力,锻炼了自己的编程能力,受益匪浅。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值