软工作业-WC程序(java实现)

 

 

 

WC个人项目博客

 

github项目传送门:https://github.com/Lock98/WCount

 

一、项目相关要求

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

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

具体功能要求:
程序处理用户需求的模式为:

wc.exe [parameter] [file_name]

基本功能列表:

  • wc.exe -c file.c     //返回文件 file.c 的字符数
  • wc.exe -w file.c    //返回文件 file.c 的词的数目  
  • wc.exe -l file.c      //返回文件 file.c 的行数

扩展功能:

  • -s   递归处理目录下符合条件的文件。
  • -a   返回更复杂的数据(代码行 / 空行 / 注释行)。

 

二、PSP开发耗时

PSP2.1

 

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 40 52

· Estimate

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

 40 52

Development

开发

 710 600

· Analysis

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

 120 140

· Design Spec

· 生成设计文档

 60 50

· Design Review

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

 30 20

· Coding Standard

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

 30 40

· Design

· 具体设计

 120 60

· Coding

· 具体编码

 210 200

· Code Review

· 代码复审

 40 30

· Test

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

 100 60

Reporting

报告

 100 80

· Test Report

· 测试报告

 40 40

· Size Measurement

· 计算工作量

 30 30

· Postmortem & Process Improvement Plan

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

 30 30

合计

 850740

 

三、设计程序流程

四、关键代码

 主类代码:(启动程序)main.java

 package com.SCL.BasicDemand;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

public class main{
public static void main(String[] args) {

while (true){

// 输出面板
System.out.println("\n---------------------3116005153 WC程序---------------------");
System.out.println("************ ***********");
System.out.println(" ** -all 返回字符数、单词数、行数 ");
System.out.println(" ** -a [文件路径] 统计代码行/空行/注释行 ");
System.out.println("-----------------------------------------------------------");

// 获取输入指令

System.out.print("[Please...] 请输入命令:");
Scanner input=new Scanner(System.in);
// String c=input.next();
String m=input.nextLine();
String arr[]=m.split("\\s");

// 根据获取指令来执行函数
try{
switch(arr[0]){
case"-all":Counter.counter(); break; //返回字符数、单词数、行数
case"-a": Code.code(arr[0]) ;break; //统计代码行 / 空行 / 注释行
default:System.out.println("\n******** 不存在该功能指令!");break;
}
} catch (FileNotFoundException e) {
System.out.println("\n******** 发生错误:输入路径文件找不到!!! **********");
} catch (IOException e){
System.out.println("\n******** 发生错误:文件读入发生异常!!! **********");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

 逻辑函数代码:

(基本功能整合)

package com.SCL.BasicDemand;

import javax.swing.*;
import java.io.*;
import java.util.Scanner;

public class Counter {
public static void counter( ) throws Exception {
// 统计一个文件的字符数,单词数,行数
Scanner input = new Scanner(System.in);

System.out.println("请输入路径");
String path = input.next();

File file = new File(path);
FileReader reader = new FileReader(file);
int countChar = 0;
int countword = 0;
int countline = 0;
InputStreamReader isr = new InputStreamReader(new FileInputStream(path));
//InputStreamReader将字符流向字节流转换。

BufferedReader br = new BufferedReader(isr);//使用缓冲区,可以使用缓冲区的read(),readLine()方法;
//readLine每次读取一行,read()读取整个文件,是生成文件内容最直接的方式,

while(br.read()!=-1)//read()=-1代表数据读取完毕
{
String s = br.readLine();
countChar += s.length();//字符个数就是字符长度
countword += s.split(" ").length;//split() 方法用于把一个字符串分割成字符串数组,字符串数组的长度,就是单词个数
countline++;//因为是按行读取,所以每次增加一即可计算出行的数目
}
isr.close();//关闭文件

System.out.println("char count "+countChar);
System.out.println("word count "+countword );
System.out.println("line count "+countline);
}
}


(拓展功能)
package com.SCL.BasicDemand;
import java.io.*;
import java.util.Scanner;
import java.util.regex.Pattern;

public class Code{
static int annotationLine = 0;
static int blankLine;
static int codeLine;
static int totalLine;


public static void code(String s)throws FileNotFoundException {
System.out.println("请输入要统计代码量的java文件:");
Scanner input = new Scanner(System.in);
String filePath = input.nextLine();
File file = new File(filePath);
Start(file);
System.out.println("----------统计结果---------");

System.out.println(file + "文件/目录总行数:" + totalLine);
System.out.println("代码行数:" + codeLine);
System.out.println("注释行数:" + annotationLine);
System.out.println("空白行数:" + blankLine);


} private static void Start(File file) throws FileNotFoundException {
if (file == null || !file.exists())
throw new FileNotFoundException(file + ",文件不存在!");



if (file.isDirectory()) {
File[] files = file.listFiles(new FileFilter() {

@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".java") || pathname.isDirectory();
}
});

for (File target : files) {
Start(target);
}
} else {
BufferedReader bufr = null;
try {
// 将指定路径的文件与字符流绑定
bufr = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
} catch (FileNotFoundException e) {
throw new FileNotFoundException(file + ",文件不存在!" + e);
}

// 定义匹配每一行的正则匹配器
Pattern annotationLinePattern = Pattern.compile("((//)|(/\\*+)|((^\\s)*\\*)|((^\\s)*\\*+/))+",
Pattern.MULTILINE + Pattern.DOTALL); // 注释匹配器(匹配单行、多行、文档注释)

Pattern blankLinePattern = Pattern.compile("^\\s*$"); // 空白行匹配器(匹配回车、tab键、空格)

String line = null;
try {
while((line = bufr.readLine()) != null) {
if (annotationLinePattern.matcher(line).find()) {
annotationLine ++;
}

if (blankLinePattern.matcher(line).find()) {
blankLine ++;
}
else {
codeLine++;// 除空白行和注释行外,其余皆为代码行
}

totalLine ++;
}
} catch (IOException e) {
throw new RuntimeException("读取文件失败!" + e);
} finally {
try {
bufr.close(); // 关闭文件输入流并释放系统资源
} catch (IOException e) {
throw new RuntimeException("关闭文件输入流失败!");
}
}
}
}
}

五、测试运行

 
 

程序启动:

测试文件

 

测试结果

 

统计代码行、注释行、空行

测试文件及结果

 
 

 

 

 

六、遇到的困难及解决方法

 
 

# 选择实现语言的困难:

自己当初看到这个作业的时候,需要实现一个命令行程序,当时就十分纠结到底要用什么语言去实现。因为脚本语言和超文本语言都无法实现这样的功能,所以必须要另作打算。

 
 

# 编程语言不熟悉的困难:

 
 

由于太久没要写java,在编程的过程当中需要边查边写逻辑,导致写得有点慢。

 
 

# 功能实现的困难:

 
 

开始编写读取文件的时候,选择的buffer读取文件流功能,发现由于个人的问题,导致程序结果不理想。后来选择使用read()函数来进行对文件的读取操作,通过二进制流来操作。这样对于基础的判断行数、单词书、字符数功能,比buffer要实现得稍微简单一点。

 
 

# 做过的尝试:

 
 

最初,选择使用pathon来实现这个功能程序,后来选择的是c语言,但是后来又觉得习惯了面向对象编程,就想起来了大二学习的一门选修java,所以最终选择了 java 这门语言实现。

 
 

 

 
 

# 解决:

 
 

最后,简单地实现了基础功能以及一个拓展功能。

 
 

# 有所收获:

 
 

在遇到困难的时候,一定要经过自己的思考之后,再去了解是如何实现的。这样才能够更好地理解和实现这个功能。多点尝试不同的方法效果更好。

 
 

 

 
 

七、项目小结

 
 

通过这次作业,重新回顾了一下Java的知识,同时也学会了从0到1实现一个程序,从预估、设计、编码、开发、测试、文档等流程中锻炼自己。

 
 

第一锻炼了养成做电子笔记的习惯,第二也有了写博客的概念,同时也增强了自己代码能力外的其他学习能力。

 
 

 

 
 

(完)

 
 

 

转载于:https://www.cnblogs.com/lock98/p/9630295.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值