个人项目作业
项目github地址:https://github.com/gduthai/WC2
项目相关要求
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 文件的代码行数、空行数、注释行数。
PSP
PSP2.1 |
Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
· Estimate | · 估计这个任务需要多少时间 | 30 | |
Development | 开发 | ||
· Analysis | · 需求分析 (包括学习新技术) | 60 | |
· Design Spec | · 生成设计文档 | 120 | |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | ||
· Design | · 具体设计 | 60 | |
· Coding | · 具体编码 | 100 | |
· Code Review | · 代码复审 | ||
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | |
Reporting | 报告 | ||
· Test Report | · 测试报告 | 60 | |
· Size Measurement | · 计算工作量 | 20 | |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | |
合计 | 620 |
遇到的困难及解决方法
1.不知道怎么判断单词的个数,自己想了一些算法,但是总是失败。之后去查询了网络,才知道具体的算法, 而且这个算法很简单。
2.程序刚开始总是不能运行,显示fopen()函数的错误,我也百思不得其解,也检查了一遍我的代码,发现是没有问题的。后来查CSDN才发现,出现这个问题的原因是我开了软件的SDL检查,开启这个插件的 话但凡程序有编译器警告的内容就不能运行。后来关闭了这个插件,终于可以编译运行了。
3.当初学习c语言的时候,并没有学习文件操作的内容,看到这个感觉很懵,找到了《c primer plus》电子书,自学了文件操作的内容,才开始写项目。
解题过程:
拿到这个项目,我首先想到的是用JAVA语言做,但是奈何JAVA刚学不熟悉,于是就改用c语言。首先这哥题目的理解我花了很长时间,慢慢地才想到这原来是一个统计程序特征的工具,然后才开始着手做项目,所以在计划方面是用了很长的时间的。这个题目的三个函数有一个共同点,就是用文件getc()函数读出每一个字符,然后识别字符特征来判断行数,列数,单词数。
设计实现过程
3个功能对应3个函数,一开始我就想到要分别设计统计行数,字符数,单词数的三个函数。并用主函数调用他们,用主函数实现交互的动作。
代码说明
计算字符数
这个功能是用getc函数一个一个读入文件字符,直到文件到达结尾。
int charnumber(char* filename) {
int num = 0; //统计字符数
char c;
FILE* fp;
fp = fopen(filename, "r"); //用“只读”打开文件
if (!fp)
exit(-1);
c = fgetc(fp);
while (!feof(fp)) { //feof函数是检查文件是否运行到末端的函数
num++;
c = fgetc(fp);
}
fclose(fp);
return num;
}
计算单词数
计算单词数的过程是,先读入字符,判断是否为字母 不是则flag=0。如果是字母且flag=0,说明这是个单词,且没有被统计过,则单词数+1。
int wordnumber(char* filename) { //统计单词数
int num = 0;
int flag = 0;
char c;
FILE* fp;
fp = fopen(filename, "r");
if (!fp)
exit(-1);
c = fgetc(fp);
while (!feof(fp)) {
c = fgetc(fp);
if (c < 'A' || (c > 'Z' && c < 'a') || c>'z')
flag = 0;
else if (flag == 0) { //如果是字母且flag=0 则单词数加一
flag = 1;
num++;
}
}
fclose(fp);
return num;
}
统计行数
一个一个读入字符,当字符是‘\n’换行符时则行数+1,用lc代表前一个字符,用来统计末行,若有末行则行数+1。这个函数有一个漏洞,就是当文件时空文件时仍然显示文件行数为1,所以我添加了一行代码,当此文件字符为0时则行数返回0。
int linenumber(char* filename) {//统计行数
FILE* fp = NULL;
int c, lc = 0;
int line = 0;
fp = fopen(filename, "r");
if (wordnumber(filename) == 0) //当字符数为0时,返回0
return 0;
while ((c = fgetc(fp)) != EOF) {
if (c == '\n') //若读到‘\n’符号,则行数+1
line++;
lc = c;
}
if (lc != '\n') line++; //加入末行
return line;
}
主函数
用c[3]读入操作命令,并通过c[1]判断要执行什么操作显示出需要的数,用filename读出文件名,然后对这个文件名进行操作。
int main() {
int i = 0;
FILE* fp;
int c_num, w_number, l_number;
char c[3];
char filename[20];
printf("输入命令wc.exe");
scanf("%s %s", c, filename);
if ((fp = fopen(filename, "r")) == NULL) { //若找不到文件,则输出 no found
printf("no found");
return 0;
}
switch (c[1]) {
case 'c': {printf("char number=%d\n", charnumber(filename)); break; }
case 'w': {printf("word number=%d\n", wordnumber(filename)); break; }
case 'l': {printf("line number=%d\n", linenumber(filename)); break; }
}
getchar();
return 0;
}
项目测试
回归测试
在主函数中加入了for语言连续运行三次以方便测试3个功能
空文件
只有一个字符的文件
只有一个单词的文件
只有一行的文件
标准源文件
经检验这些结果都是正确的所以该程序的代码覆盖率是100%
实际花费时间
PSP2.1 |
Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
· Estimate | · 估计这个任务需要多少时间 | 30 | 20 |
Development | 开发 | ||
· Analysis | · 需求分析 (包括学习新技术) | 60 | 80 |
· Design Spec | · 生成设计文档 | 120 | 120 |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | ||
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 100 | 120 |
· Code Review | · 代码复审 | ||
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 120 |
Reporting | 报告 | ||
· Test Report | · 测试报告 | 60 | 30 |
· Size Measurement | · 计算工作量 | 20 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 20 |
合计 | 620 | 490 |
项目小结
1.事情要提前规划完,并且提前做完,不要快要到时间才慌慌张张。
2.我对代码还不够熟悉,需要学习更多知识,而且实践更多。
3.拓展功能还有高级功能都没有实现,这个很遗憾。
4.没有学会高级的调试技巧,运用高级的工具能使测试工作事半功倍。这件事之后一定要学会。