零、GitHub地址
https://github.com/King-Authur/Word-count
一、项目的相关要求
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 返回更复杂的数据(代码行 / 空行 / 注释行)。
空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
代码行:本行包括多于一个字符的代码。
注释行:本行不是代码行,并且本行包括注释。
一个有趣的例子是有些程序员会在单字符后面加注释:
} //注释
在这种情况下,这一行属于注释行。
[file_name]: 文件或目录名,可以处理一般通配符。
高级功能:
-x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。
需求举例:
wc.exe -s -a *.c
返回当前目录及子目录中所有*.c 文件的代码行数、空行数、注释行数。
简化后的要求
基本功能
支持 -c
支持 -w
支持 -l
扩展功能
支持 -s 参数
支持 -a 参数
支持各种文件的通配符(*,?)
高级功能
基本的Windows GUI 程序操作
支持通过图形界面选取文件
支持通过图形界面展现文件的信息
二、遇到的困难和解决方法
(一)如何使用命令行运行程序
查阅相关资料后,总结了知识点和方法,并写了一遍博客
https://blog.csdn.net/WHY995987477/article/details/104905196
(二)如何实现基础功能
首先定好判断的标准
字符:字母、计算机字符
单词:由一个或一个以上的连续字母所构成的字符串
行:空行与非空行的总和
代码行:非空行且非注释行
空行:由空格、回车、tab、} 构成的行
注释行:含有 \\ 并且它不被包含在两个双引号中
思路是,按照该标准一步一步实现代码,计算出结果即可。
(三)如何递归查询文件夹
目前找到的方法是学习MFC,调用Windows的API,如 FindFirstFile 和 FindNextFile 函数,还未解决,目前还在学习中。
(四)通配符 ?和 * 如何实现
未解决
(五)图形界面的实现
未解决
三、关键代码 和 设计说明
设计图
采用了面向过程的设计
目前实现了四个函数
void get_flag(int argc, char **argv);
void calculate_information(char *file_path);
bool is_char(char ch);
void display();
关键代码
该函数用于计算出所有题目中要我们求的数据,包括字符、单词、行、代码行、空行、注释行的数目。
void calculate_information(char *file_path);
代码的实现
void calculate_information(char *file_path){
FILE* fp = fopen(file_path, "r");//只读打开文件路径指向的文件
if(fp == NULL){//检测是否是有效路径
printf("!!!错误!!!\n请检查文件路径是否正确\n");
exit(-1);//关闭程序
}
char buffer[maxn_word_of_line];//存取当前行数据的缓存区
while(!feof(fp))//是否到文件尾
{
buffer[0] = '\0';
fgets(buffer, maxn_word_of_line, fp);//一整行读取
res.line++;
int len = strlen(buffer);
bool left_blank = true, is_Empty = true;
for(int i = 0; i < len; i++)
{
if(is_char(buffer[i]))///如果是非空字符
{
res.character++;///那么字符数要增加
is_Empty = false;///并且这一行不为空
}
if(isalpha(buffer[i]))///当它是字母时
{
if(left_blank)///当左边被其他字符隔开时
{
res.word++;///单词数目+1
left_blank = false;
}
}
else///当前字符不是字母
{
left_blank = true;///则视为它是隔开单词的字符
}
}
if(is_Empty)///这一行为空行
{
res.empty_line++;
}
else///这一行非空,判断一下是否为注释行
{
bool left_quote = false;///左双引号
bool slanting_bar = false;///斜杆
bool explain_flag = false;///注释行的标记
///过滤掉包含于字符串输出的“假注释”,例如:printf("//");
for(int i = 0; i < len; i++)
{
if(buffer[i] == '"')///如果是双引号
{
if(!left_quote)///如果没有左边匹配的双引号
{
left_quote = true;
}
else
{
left_quote = false;///左边有可以匹配的双引号
}
}
if(buffer[i] == '/' && buffer[i + 1] == '/')///如果有连续的两个反斜杠
{
slanting_bar = true;
}
if(!left_quote && slanting_bar)///如果斜杠没有被包含在字符串的输出中,则这一行必定为注释行
{
res.explain_line++;
explain_flag = true;
break;
}
}
if(!explain_flag)///不是注释行,就是代码行
{
res.code_line++;
}
}
}
}
该函数会逐行读取整个文件,每行遍历两次即可计算出改行的所有信息,信息存放在结构体内,不断更新直到读取到文件尾。
输出时根据传入的参数决定输出哪些内容。
四、测试运行
基础部分与扩展部分中的 -a 一起测试
1、测试只有两行空白行的文件
无误
2、测试只含有两个单词、十个字符的文件
无误
3、测试一份简单的代码
检验可知
printf("\\");
没有被误认为注释行
printf("Hello world\n");//Hello world
和}//注释
正确的被识别为注释行
其他数据的结果也无误
测试文件路径
4、输入错误的文件路径
会有错误提示
五、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 40 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 15 | 10 |
Development | 开发 | 360 | 400 |
· Analysis | · 需求分析 (包括学习新技术) | 60 | 40 |
· Design Spec | · 生成设计文档 | 20 | 20 |
· Design Review | · 设计复审 (和同事审核设计文档) | 10 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
· Design | · 具体设计 | 30 | 30 |
· Coding | · 具体编码 | 120 | 100 |
· Code Review | · 代码复审 | 20 | 20 |
· Test | · 测试(自我测试,修改代码,提交修改) | 30 | 40 |
Reporting | 报告 | 30 | 35 |
· Test Report | · 测试报告 | 20 | 20 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 40 |
合计 | 905 | 825 |
六、项目小结
1、不熟悉面向对象编程,使用了面向过程编程
2、没有识别/**/注释的代码
3、递归文件夹下的文件 和 图形界面 功能尚未完成
4、不熟悉GitHub的使用
5、代码实现和测试时出现了一些小错误,导致花费了更多的时间
6、不会用Windows SDK编程
7、对自己的成果不满意,后续还会继续更新和完善
8、
七、参考来源
软件工程个人项目作业:https://edu.cnblogs.com/campus/gdgy/se18_12/homework/10477
项目博客模板:https://www.cnblogs.com/vertextao/p/7469789.html
《构建之法》:https://max.book118.com/html/2019/0901/6141233210002101.shtm
VS2015安装与C++进行简单单元测试:https://www.cnblogs.com/xiaoyongwu/p/5289964.html