个人项目 WordCount

个人项目

github地址:(https://github.com/CJK000/WordCount)

编程语言 C++

开发环境 VS2017

题目描述

Word Count

  1. 实现一个简单而完整的软件工具(源程序特征统计程序)。
  2. 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
  3. 进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。

WC项目要求

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 返回更复杂的数据(代码行 / 空行 / 注释行)。

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

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

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

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

高级功能:

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

需求举例:
  wc.exe -s -a *.c

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


解题思路

个人项目要求统计文本的字符数、单词数、行数,并且在实现过程中进行单元测试、回归测试、速度测试。所以需要学习对文件的读取操作,学习在VS中进行单元测试,将项目文件保存在github中,所以先进行了如下内容的学习:

学习课件中的C++单元测试教程: [第二届构建之法论坛] 预培训文档(C++版)

学习 github 和 git 的使用教程: 【教程】学会Git玩转Github【全】

学习C++中 ifstream 类的使用

设计实现过程

首先设计WordCount类,仅有一个私有变量 ifstream对象,由构造函数对其进行初始化打开文件,析构函数关闭文件,WordCount类有四个方法,其中一个检查文件是否成功打开,另外三个方法分别实现项目需求。

因为本程序运行一次即可结束,所以文件在初始化对象时将其打开,之后在程序结束时再自动调用析构函数对其关闭,所以在每次统计文本的函数开始时先执行 file.clear();file.seekg(ios::beg); 以保证文件从头正确读取。

class WordCount {
private:
	ifstream file;
public:
	WordCount(char *str) {
		file.open(str);
	}
	bool CheckFile() {
		return file.is_open();
	}
	~WordCount()
	{
		file.close();
	}
	unsigned int CountChar();
	unsigned int CountWord();
	unsigned int CountRow();
};

代码说明

unsigned int WordCount::CountChar() {
	file.clear();
	file.seekg(ios::beg);
	unsigned char_num = 0;
	string str;
	while (!file.eof())
	{
		getline(file, str);
		char_num += str.length();
	}
	return char_num;
}

统计字符数函数,逐行读取,,累加每一行的字符数。

unsigned int WordCount::CountWord() {
	int i;
	file.clear();
	file.seekg(ios::beg);
	unsigned int word_num = 0;
	string str;
	while (!file.eof())
	{
		getline(file, str);
		bool isWord = false;	//标记当前字符是否为一个单词部分
		for (i = 0; i < (int)str.length(); i++) {
			if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) {	//当前字符是一个字母
				if (isWord == false) {	//如果前一个字符不是单词的一部分,那单词数加一,改变标记
					word_num++;
					isWord = true;
				}
			}
			else {
				isWord = false;
			}
		}
	}
	return word_num;
}

统计单词数函数,逐行读取,逐行统计,统计算法见注释。

unsigned int WordCount::CountRow() {
	file.clear();
	file.seekg(ios::beg);
	unsigned int row_num = 0;
	string str;
	while (!file.eof())
	{
		getline(file, str);
		row_num++;
	}
	return row_num;
}

统计行数,每读取一行,行数加一,值到文件尾。


测试运行

测试文档:

运行结果:

单元测试


PSP表格

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

项目总结

编码之前应该更全面地完成整体地设计和类的设计,编码能更轻松

posted @ 2020-03-24 21:24  CJK000  阅读(108)  评论(0)    收藏  举报