github地址:https://github.com/Spartaright/wc
一、题目描述
实现一个简单而完整的软件工具(源程序特征统计程序)。
进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。
wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:程序处理用户需求的模式为:wc.exe [parameter] [file_name]
二、解题思路
统计字符数,行数的实现不算困难,只需要在意空格、换行符之类的操作即可;重点在于如何实现统计单词数的算法,参考C语言的教科书就可以解决。对于我来说,比较困难的是对文件的操作,因为之前从来没试过,对于如何读取文件的信息还是比较陌生的。因此在着手准备前针对性地学习了fopen、fclose,fgerc之类必要函数的算法。由于到目前为止大多数时间都是使用C语言,再加上C语言偏底层的特性,对文件操作比较方便,所以这次的个人项目用C来实现。
三、代码
1、字符数统计
int charcalculate(char *file) { FILE *fp = NULL; int charcount = 0; fp = fopen(file, "r");//打开一个文本文件 if (fp == NULL) { printf("文件寻找失败! "); exit(-1); } char filechar; filechar = fgetc(fp); while (filechar != EOF) { filechar = fgetc(fp);//读取文件中的字符 charcount++;//统计字符数 } fclose(fp); return charcount; }
2、单词数统计
int wordcalculate(char *file) { FILE *fp = NULL; int wordcount = 0; fp = fopen(file, "r"); if (fp == NULL) { printf("文件寻找失败! "); exit(-1); } char fileword; int word; fileword = fgetc(fp); while (fileword != EOF) { fileword = fgetc(fp); if (fileword<'A' || (fileword > 'Z'&&fileword < 'a') || fileword>'z') { word = 0; } else if (word == 0) { word = 1; wordcount++; } } if (word == 0) { wordcount++; word = 1; } return wordcount; }
3、行数统计
int linecalculate(char *file) { FILE *fp = NULL; int linecount = 0; fp = fopen(file, "r"); if (fp == NULL) { printf("文件寻找失败! "); exit(-1); } char fileline; fileline = fgetc(fp); while (fileline != EOF) { if (fileline == ' ') {//出现换行时,统计行数 linecount++; fileline = fgetc(fp); } else { fileline = fgetc(fp); } fclose(fp); return linecount + 1; } }
4、主函数
#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() { char file[200], intput; printf("请输入用户命令:wc.exe-"); intput = getchar(); switch (intput) { case 'c': printf("请输入文件名:"); scanf("%s", &file); int charcount = 0; charcount = charcalculate(file); printf("文件字符数为:%d ", charcount); break; case 'w': printf("请输入文件名:"); scanf("%s", &file); int wordcount = 0; wordcount = wordcalculate(file); printf("文件单词数为:%d ", wordcount); break; case 'l': printf("请输入文件名:"); scanf("%s", &file); int linecount = 0; linecount = linecalculate(file); printf("文件行数为:%d ", linecount); break; default: printf("错误操作!请重新输入!"); } getchar(); return 0; }
四、项目测试
1、空文件
2、只含一个字符
3、只有一行
4、一个典型的源文件
五、心得总结
1、本次作业编译环境为vs2017,对C语言的支持并不是很好(而对于C++和C#比较完善),因此在编写的时候需要混杂有C++的风格,感觉比较棘手;最终编译的时候也是频繁出现无法找到pdb文件这一错误(错误代码:c4996),后来有试过把scanf,fopen之类的函数换成C++风格的scanf_s和fopen_s,但是效果并不理想,最终经过多次尝试,在预处理的时候加上#pragma warning(disable:4996)这一段后才能勉强运行,但是运行效率却大打折扣了,由于个人能力所限,改进过程只能放下了。
2、通过这次项目的锻炼,我体会到了个人软件过程能够使我按照一套标准的流水线的步骤去处理任务,由于自身能力的不足,在这个过程中出现了许多的困难,而且也有很多东西不达标,但是依旧体会到了这个过程的重要性,今后会加强训练自己,努力掌握个人软件过程。