WordCount
GitHub地址:https://github.com/Aabon00/wordcount
PSP2.1表格
PSP2.1 |
PSP阶段 |
预估耗时 (分钟) |
实际耗时 (分钟) |
Planning |
计划 |
20 | 25 |
· Estimate |
· 估计这个任务需要多少时间 |
15 | 10 |
Development |
开发 |
500 | 600 |
· Analysis |
· 需求分析 (包括学习新技术) |
60 | 90 |
· Design Spec |
· 生成设计文档 |
30 | 40 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
30 | 20 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
20 | 10 |
· Design |
· 具体设计 |
40 | 30 |
· Coding |
· 具体编码 |
500 | 600 |
· Code Review |
· 代码复审 |
20 | 15 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
30 | 40 |
Reporting |
报告 |
20 | 20 |
· Test Report |
· 测试报告 |
20 | 20 |
· Size Measurement |
· 计算工作量 |
15 | 30 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
15 | 10 |
合计 |
1335 | 1560 |
解题思路:构建实现各个功能的函数,基本功能有统计文本单词数、字符数和行数,扩展功能有统计注释行数、空行数和代码行数。询问同学得知main(argc,**argv)函数中的参数argv为功能名或文本名,而argc为这些的个数。由此可依据输入的各个参数判断各个功能名是否出现并依据这个判断是否调用相应函数。得到对应的数据后按照规范输出即可。查询资料也能学到对文件夹的读操作和写操作。
程序实现过程:
程序包含如下几个函数:
对于基本功能:
CountChars()统计文本的字符数;
WordLine()统计一行的单词数;
CountWords()统计文本的单词数,调用了函数WordLine();
CountLines()统计文本行数;
对于扩展功能,仅实现了-a的功能:
rem()去掉某一字符;
BlaLine()统计空行数,调用了函数rem();
ExLine()统计注释行数,本程序仅支持行注释;
CodeLine()统计文本代码行数,调用了函数rem();
代码说明:
//统计一行单词个数 int WordLine(const char *szLine) { int n=0; int flag=0; for(int i=0;i<strlen(szLine)-1;i++) { if(*(szLine+i)==' '||*(szLine+i)==',') { flag=0; } else { if(flag==0) { flag=1; n++; } } } return n; } //统计文本单词个数 int CountWords(char *szFile) { int n=0; FILE *fp; char buffer[1024]; if ((fp=fopen(szFile,"r"))==NULL) { return -1; } while (!feof(fp)) { if (fgets(buffer, sizeof(buffer),fp)!=NULL&&buffer[0]!='\0') n+=WordLine(buffer); } fclose(fp); return n; }
统计文本单词个数不妨一行行地统计。函数WordLines()即统计一行单词的个数,先设一个标记flag=0,循环逐个读入一行的字符,为空格或逗号时将flag置为0;不为空格或逗号时,将flag置为1并计数n加1;最后返回n的值即为一行的单词个数。CountWords()函数中声明一个文件指针,打开szFile文件,fgets()读取文件中的一行,然后调用WordLine()函数直到文件结尾。
//去掉字符串中的某些字符 int rem(char *r,char ex) { char data[100]={0}; strcpy(data,r); int i=0,j=0; for(;data[i]!='\0';i++) { if(data[i]!=ex) data[j++]=data[i]; } data[j]='\0'; strcpy(r,data); } //统计文本代码行数 int CodeLine(char *szFile) { int n=0; FILE *fp; char buffer[1024]; if ((fp=fopen(szFile,"r"))==NULL) { return -1; } while (!feof(fp)) { fgets(buffer,sizeof(buffer),fp); rem(buffer,' '); rem(buffer,'\t'); rem(buffer,'\n'); if(strlen(buffer)>1&&strncmp(buffer,"//",2)!=0) n++; } fclose(fp); return n; }
由需求可知一行的可见字符长度大于1且开头无“//”字符时为代码行。则可先将一行中的空格、换行符、Tab符去掉,并用strncmp()函数判断一行的起始是否“//”。rem()函数便是消去字符串中的某个字符。声明一个数组保存一行的字符串,for循环至字符串结尾,循环中依次将不等于ex的字符传入到数组中,最后用strcpy()函数将数组传入到指针参数里。CodeLine()函数中类似CountWords的做法依次读取文件的一行调用rem()函数并用strlen()函数计算字符长度然后判断起始是否“//”,若长度大于1且不为“//”,则计数n+1.
测试设计过程:
测试需要覆盖程序中所有可执行语句,所以要尽量测试出程序功能的问题。主要风险有:注释行,空行代码行的判定。程序的基本功能有:统计文件的字符个数、单词个数、行数。还需要测试文件是否存在,功能参数混用等情况
(1)测试功能-w
输入:wc.exe -w test.c
(2)测试功能-l
输入:wc.exe -l test.c
(3) 测试功能-c
输入:wc.exe -c test.c
(4) 测试功能-o
输入:wc.exe -w test.c -o result.txt
(5)测试扩展功能-a
输入:wc.exe -a test.c
(6)功能混用
输入:wc.exe -w -l -c -a test.c -o result.txt
(7)测试打乱文件名输入位置
输入:wc.exe test.c -w -c -a -l -o result.txt
(8)测试文件名不存在的情况
输入:wc.exe -w -c -a testno.c
(9)测试输入参数不存在的情况
输入:wc.exe -w -y -a test.c
(10)测试文件名不存在的情况
输入:wc.exe -w -a -l -c test.c -o out.txt
参考文献:
https://blog.csdn.net/Athenaer/article/details/7876614
http://blog.csdn.net/yhawaii/article/details/7361302
http://blog.csdn.net/hancunai0017/article/details/7032383