软件工程作业 - 实现WC功能(java)
项目地址:https://github.com/yogurt1998/WordCount
要求
- 基本要求
- -c 统计文件字符数(实现)
- -w 统计文件单词数(实现)
- -l 统计文件行数(实现)
 
- 扩展功能
- 递归处理目录下符合条件的文件。(实现)
- 返回更复杂的数据(代码行 / 空行 / 注释行)(实现)
 
- 高级功能
- 实现图形化界面(未实现)
 
PSP
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| Planning | 计划 | 40 | 65 | 
| · Estimate | · 估计这个任务需要多少时间 | 30 | 45 | 
| Development | 开发 | 450 | 600 | 
| · Analysis | · 需求分析 (包括学习新技术) | 60 | 90 | 
| · Design Spec | · 生成设计文档 | 60 | 60 | 
| · Design Review | · 设计复审 (和同事审核设计文档) | 30 | 30 | 
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 | 
| · Design | · 具体设计 | 30 | 30 | 
| · Coding | · 具体编码 | 150 | 150 | 
| · Code Review | · 代码复审 | 150 | 150 | 
| · Test | · 测试(自我测试,修改代码,提交修改) | 60 | 60 | 
| Reporting | 报告 | 100 | 100 | 
| · Test Report | · 测试报告 | 60 | 60 | 
| · Size Measurement | · 计算工作量 | 30 | 30 | 
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 | 
| 合计 | 1310 | 1530 | 
设计
main.java
主函数:一个循环获取输入命令并分隔出指令和文件路径。
统计函数:通过IO流获取文件内容并统计字符数、行数、单词数等。
文件判断函数:判断是否为文件夹或者文件以实现递归处理功能
AFile.java
代表着字符数等六个属性。

代码
main()函数
public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		do {
			String filename = null;
			String bString = null;
			System.out.println("请输入命令(格式:[parameter] [file_name])");
			while (true) {
				Scanner scanner = new Scanner(System.in); // 获取键盘输入
				if (scanner.hasNext()) {
					bString = scanner.next();
				}
				if (bString.equals("-c") || bString.equals("-w")
						|| bString.equals("-l") || bString.equals("-s")
						|| bString.equals("-a")) {
					if (scanner.hasNextLine()) {
						filename = scanner.next();
					}
					break;
				} else {
					System.out.println("错误!请重新输入!");
				}
			}
				String filepath = "D:\\test\\" + filename; // 在绝对路径中打开
				File file = new File(filepath);
				if (!file.exists()) {
					System.out.println("文件不存在");
					continue;
				}
				AFile aFile = new AFile();
				aFile = findFiles(filepath);
				if (bString.equals("-c"))
					System.out.println("字符数为" + aFile.charNumb);
				else if (bString.equals("-w"))
					System.out.println("单词数为" + aFile.wordNumb);
				else if (bString.equals("-l"))
					System.out.println("行数为" + aFile.lineNumb);
				else if (bString.equals("-a"))
					System.out.println("空行数为:" + aFile.empleLine
							+ " 代码行数为:" + aFile.codeLine + " 注释行数为:" + aFile.nodeLine);
		} while(true);
	}
findFiles()函数:通过递归处理文件
private static AFile findFiles(String file_path) {
		File file = new File(file_path);
		AFile aFile = new AFile();
		if (file.isDirectory()) { // 判断为文件夹
			File[] files = file.listFiles(); // 获取文件列表
			if (files == null) {
				System.err.println("找不到");
			} else if (files.length == 0) {
				System.out.println("目录为空");
			} else {
				for (File f : files) { // 循环处理文件
					if (f.isDirectory()) // 判断为文件夹
						findFiles(f.getPath());
					else if (f.isFile()) { // 判断为文件
						System.out.println("文件名为:" + f.getName() + "\n字符数为" + getCount(f.getPath()).charNumb +
								"\n单词数为" + getCount(f.getPath()).wordNumb +
								"\n行数为" + getCount(f.getPath()).lineNumb +
								"\n空行数为:" + getCount(f.getPath()).empleLine +
								"\n代码行数为:" + getCount(f.getPath()).codeLine +
								"\n注释行数为:" + getCount(f.getPath()).nodeLine);
					}
				}
			}
		} else if (file.isFile() && file.exists()) { // 判断为文件
			aFile = getCount(file.getPath());
		}
		return aFile;
	}
getCount()函数:通过BufferedReader获取文件内容并判断
private static AFile getCount(String filepath) {
		AFile aFile = new AFile();
		try {
			BufferedReader brin = new BufferedReader(new FileReader(filepath));
			String s;
			int state = 0; // 判断是否在单词内
			// 使用正则表达式判断注释行
			String regxNodeBegin = "(\\S?)\\s*/\\*.*";
			String regxNodeEnd = "(.*\\*/\\s*)\\S?";
			String regxNode = "(\\s*)(\\S?)(//+).*";
			while ((s = brin.readLine()) != null) {
				++ aFile.lineNumb;
				int countLetter = 0; // 判断非空格字符数量
				for (int i = 0; i < s.length(); i++) {
					++aFile.charNumb;
					Character c = s.charAt(i);
					++countLetter;
					if (c == ' ' || c == '\n' || c == '\t') {
						state = 0;
						--countLetter;
					}
					else if (state == 0) {
						state = 1;
						++aFile.wordNumb;
					}
				}
				if (s.matches(regxNodeBegin) || s.matches(regxNodeEnd)
						|| s.matches(regxNode))
					++aFile.nodeLine;
				else if (countLetter > 1) // 如果非空格字符数多于1
					++aFile.codeLine;
				else
					++aFile.empleLine;
			}
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println(e.getMessage());
		}
		return aFile;
	}
测试运行
测试文件:

测试结果:

总结
- 根据在软件工程课堂上得到的知识进行分析,但没有细心分析导致递归功能一开始写错。
- 程序的思路一开始并不是很清晰导致后面很多修改以及代码繁杂。
- 学习了Git和GitHub的使用以及exe4j的使用。
- 对程序设计很不熟悉需要更多的练习。
软件工程作业 - 实现WC功能(java)的更多相关文章
- 软件工程—WC功能实现 (JAVA)
		软件工程-WC功能实现(JAVA) Github项目地址:https://github.com/Ousyoung/wc 项目要求  wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和 ... 
- 软件工程作业 - word count
		(编程和软件工程作业系列) 实践最简单的项目:WC 实践是理论的基础和验证标准,希望读者贯彻“做中学”的思想,动手实现下面的项目,并和别人的成绩相比较,分析产生差距的原因. 1. 实现一个简单而完整的 ... 
- Implementation of WC in JAVA
		Implementation of WC in JAVA github地址 相关要求 基本功能 -c [文件名] 返回文件的字符数 (实现) -w [文件名] 返回文件的词的数目 (实现) -l [文 ... 
- 实现wc部分功能  java
		GitHub地址:https://github.com/carlylewen/ruangong 相关要求 基本功能 wc.exe -c file.c //返回文件 file.c 的字符数(实现 ... 
- 个人小项目——Java实现WC功能
		这个小项目用了两种方法解决了该功能的实现. 1.两种方法的功能和具体实现 代码可以成功运行,但是有一些情况考虑不完整,一种方法用了FileOutputStream输出流,为了解决空格无法统计问题,对文 ... 
- java实现wc功能
		github项目地址:https://github.com/3216004717/ruanjiangongcheng.git 项目相关要求 基本要求 wc.exe -c file.c //返回文件 f ... 
- 算法笔记_202:第三届蓝桥杯软件类决赛真题(Java高职)
		目录 1 填算式 2 提取子串 3 机器人行走 4 地址格式转换 5 排日程 前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 填算式 [结果填空] (满分11分) 看这个算式: ☆☆☆ + ☆☆ ... 
- 软件设计模式之代理模式(JAVA)
		貌似停笔了近半个月了,实在不该啊,新的一年,时刻让自己归零. Back To Zero,就从这篇文章拉开今年的序幕吧. 这篇文章准备介绍下有关代理模式的基本概念和静态代理.动态代理的优缺点及使用方法( ... 
- 软件工程作业——Word Counter
		github地址 https://github.com/Pryriat/Word_Counter 项目说明 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命 ... 
随机推荐
- electron 大体结构
			1.Electron支持的平台: OS XWindowsLinux 2.一个标准的electron app包含的结构: Windows 或是 Linux中:electron/resources/app ... 
- Spring Boot logback
			前言 今天来介绍下spring Boot如何配置日志logback,我刚学习的时候,是带着下面几个问题来查资料的,你呢 如何引入日志? 日志输出格式以及输出方式如何配置? 代码中如何使用? 正文 Sp ... 
- 检测到有潜在危险的 Request.Form 值——ValidateRequest的使用
			1.aspx中 在 Web 应用程序中,要阻止依赖于恶意输入字符串的黑客攻击,约束和验证用户输入是必不可少的.跨站点脚本攻击就是此类攻击的一个示例. 当请求验证检测到潜在的恶意客户端输入时,会引发此异 ... 
- vs2010下载Microsoft Visual Studio 2010 Express(vs2010中文版下载)速成官方合集正式版
			http://www.xiazaiba.com/html/1832.html VB.NET 2010 Express: 2KQT8-HV27P-GTTV9-2WBVV-M7X96VC++ 2010 E ... 
- cdoj842-天下归晋            【树状数组】
			http://acm.uestc.edu.cn/#/problem/show/842 天下归晋 Time Limit: 3000/1000MS (Java/Others) Memory Lim ... 
- IIS7web服务器调试ASP.net程序遇到的一些故障的解决办法
			1. [由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面] 故障描述:[由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面] ... 
- MySQL基本操作之命令行操作
			MySQL基础操作 MySQL基础操作--命令行操作 
- php 下 html5 XHR2 + FormData + File API 上传文件
			FormData的作用: FormData对象可以帮助我们自动的打包表单数据,通过XMLHttpRequest的send()方法来提交表单.当然FormData也可以动态的append数据.FormD ... 
- sql ltrim/rtrim 字段中为中文时出现?的问题
			字段存储为中文,类型为nvarchar,使用ltrim时结果集中出现的问号,我的解决办法是:将问号replace掉 
- 基于KVM的qemu中宿主机和虚拟机间的通信
			qga是一个运行在虚拟机内部的普通应用程序(可执行文件名称默认为qemu-ga,服务名称默认为qemu-guest-agent),其目的是实现一种宿主机和虚拟机进行交互的方式,这种方式不依赖于网络,而 ... 
