个人项目 WordCount
个人项目
github地址:(https://github.com/CJK000/WordCount)
编程语言 C++
开发环境 VS2017
题目描述
Word Count
- 实现一个简单而完整的软件工具(源程序特征统计程序)。
- 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
- 进行个人软件过程(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 | · 事后总结, 并提出过程改进计划 | ||
| 合计 |
项目总结
编码之前应该更全面地完成整体地设计和类的设计,编码能更轻松
浙公网安备 33010602011771号