WordCount.exe(基于C语言)
Github链接:https://github.com/Hubbard1999/wordcount
1 项目简介
1.1 题目描述
-
实现一个简单而完整的软件工具(源程序特征统计程序)。
-
进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
-
进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。
1.2 项目要求
wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:
程序处理用户需求的模式为:
wc.exe [parameter] file_name
1.3 功能列表
基本功能列表:
wc.exe -c file.c //返回文件 file.c 的字符数 (已实现 )
wc.exe -w file.c //返回文件 file.c 的词的数目 (已实现)
wc.exe -l file.c //返回文件 file.c 的行数 (已实现)
扩展功能:
-s 递归处理目录下符合条件的文件。 (已实现)
-a 返回更复杂的数据(代码行 / 空行 / 注释行)。 (已实现)
PS:
空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
代码行:本行包括多于一个字符的代码。
注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:
} //注释
在这种情况下,这一行属于注释行。
2. PSP表
(请见 7. 实际PSP表)
3. 解题思路
- 之前只学过c和java,鉴于c比较熟悉,故选用c语言
- 经查询 c语言的main函数参数可在cmd命令行中赋值,即可实现相应的功能。
4. 设计过程
4.1 共5个功能函数及main函数
/*字符统计*/
int CharNum(char *file)
/*词数统计*/
int WordNum(char *file)
/*行数统计*/
int LineNum(char *file)
/*寻找目录下txt、cpp文件*/
int searchfile(void)
/*更多统计*/
void MoreData(char *file)
/*主函数*/
int main (int argc, char *argv[])
4.2 流程图
- 绘出除main函数外的5个流程图:
5. 代码分析
- 头文件
#include
#include
#include
#include
#include
- main函数
/*主函数*/
int main (int argc, char *argv[]){
/* 定义两个结构体 */
/* 程序开始之前计时start */
struct timeval start;
struct timeval end;
unsigned long timer;
gettimeofday(&start, NULL);
int i;
for(i=1;i
基本功能:
- 字符统计 -c
/*字符统计*/
int CharNum(char *file){
int count = 0;
FILE *fp;
char a;
fp=fopen(file,"r");
//开始
while(!feof(fp)){
a=fgetc(fp);
if(a!=' '&&a!='\n'&&a!='\t')
//除空格 换行 tab外 都当作一个字符
count++;
}
fclose(fp);
count--;
return count;
}
- 词数统计 -w
/*词数统计*/
int WordNum(char *file){
int w = 0;
FILE *fp;
int a,t = 10;
int mark = 0;
fp = fopen(file,"r");
//开始
if (CharNum(file)==0) w = 0;
else{
while(!feof(fp)){
a = fgetc(fp);
if(a==32||a==10||a==9) mark++;
// ' '||'\n'||'\t'
else{
if(a==-1) t = mark;
mark = 0;
}
if(mark==1) w++;
}
if(t==0) w++;
}
fclose(fp);
return w;
}
- 行数统计 -l
/*行数统计*/
int LineNum(char *file){
int count = 0;
FILE *fp;
fp=fopen(file,"r");
char a;
//开始
while(!feof(fp)){
a=fgetc(fp);
if(a=='\n') count++;
}
fclose(fp);
return count;
}
扩展功能:
- 寻找目录下txt、cpp文件 -s
/*寻找目录下txt、cpp文件*/
int searchfile(void){
//文件存储信息结构体
struct _finddata_t fileinfo; //保存文件句柄
long fHandle; //文件数记录器
//开始
//check .txt
int t=0;
if( (fHandle=_findfirst( "*txt", &fileinfo )) == -1L ){
printf( "当前目录下没有txt文件\n");
}
else
do{
t++;
printf("找到文件:%s\n", fileinfo.name);
}while(_findnext(fHandle,&fileinfo)==0);
printf("txt文件数量:%d\n",t);
//check .cpp
t=0;
if( (fHandle=_findfirst( "*cpp", &fileinfo )) == -1L ){
printf( "当前目录下没有cpp文件\n");
}
else
do{
t++;
printf("找到文件:%s\n", fileinfo.name);
}while (_findnext(fHandle,&fileinfo)==0);
printf("cpp文件数量:%d\n",t);
_findclose(fHandle);
return 0;
}
- 返回更复杂的数据(代码行 / 空行 / 注释行) -a
/*更多统计*/
void MoreData(char *file)
{
FILE *fp;
if ((fp=fopen(file,"r")) == NULL){
printf("找不到文件!");
exit(0);
}
int empty = 0,code = 0,note = 0,state1= 0,state2=0;
char ch;
//开始
while(!feof(fp)){
ch = fgetc(fp);
if(ch=='\n'||ch==EOF){
if(state2==0) //空行
empty++;
else if(state2==1){ //代码行
code++;
state2 = 0;
}
else{ //注释行
note++;
state2 = 0;
}
}
else if(ch!=' '&&ch!='\t'&&ch!='{'&&ch!='}'){
if(ch=='/'){
if(state2==0&&state1==0)
state1 = 1;
else if(state2==0&&state1==1){
state2 = 2;
state1 = 0;
}
}
else if(state2!=2)
state2 = 1;
}
}
printf("空行数为:%d 代码行数为:%d 注释行数为:%d\n",empty,code,note);
fclose(fp);
}
6. 回归测试
7. 实际PSP表格
*PSP2.1* | *Personal Software Process Stages* | *预估耗时(分钟)* | *实际耗时(分钟)* |
---|---|---|---|
Planning | 计划 | 40 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 400 | 460 |
Development | 开发 | 375 | 495 |
· Analysis | · 需求分析 (包括学习新技术) | 20 | 30 |
· Design Spec | · 生成设计文档 | 30 | 40 |
· Design Review | · 设计复审 (和同事审核设计文档) | 10 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 5 | 10 |
· Design | · 具体设计 | 40 | 60 |
· Coding | · 具体编码 | 180 | 240 |
· Code Review | · 代码复审 | 30 | 15 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 90 |
Reporting | 报告 | 60 | 40 |
· Test Report | · 测试报告 | 20 | 10 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 20 |
合计 | 475 | 565 |
8. 项目小结
-
使用c语言io的操作,没有用递归来完成读取目录的工作。
-
对于psp指引的开发过程尚不熟悉,分工不够明确。
-
由于使用cmd命令行的方式进行文件操作,故图形化方面无从下手。
-
即使没有选修java,也要跟着一起听,打好java基础,期待能完成更加严谨的代码程序。