1.github地址:
2.PSP表格
psp 2.1 | psp阶段 | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 10 | 5 |
Estimate | 估计这个任务需要多少时间 | 10 | 15 |
Deveploment | 开发 | 10 | 5 |
Analysis | 需求分析(包括学习新技术) | 30 | 30 |
Design Spec | 生成设计文档 | 20 | 10 |
Design Review | 设计复审(和同事审核设计文档) | 10 | 5 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 20 | 20 |
Design | 具体设计 | 30 | 50 |
Coding | 具体编码 | 380 | 400 |
Code Review | 代码复审 | 30 | 20 |
Test | 测试(自我测试,修改代码,提交修改) | 150 | 200 |
Reporting | 报告 | 10 | 10 |
Test Report | 测试报告 | 20 | 30 |
Size Measurement | 计算工作量 | 5 | 10 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 10 | 20 |
合计 | 745 | 830 |
3.解题思路
根据老师给定的需求,从基本功能开始,实现-c -w -l 功能,完成基本功能后,进行第一次代码commit 到github.
在基本功能基础上,分析扩展功能,由于扩展功能较为复杂,故我将逐个实现 -s -a -e功能,并进行单个测试,最后统一整理,编码运行成功后,进行全部功能测试。
输入均用主函数自带的String args[]参数进行接收,对接收的字符进行判断,从而进行对应操作。
对于输出到文件实现,若未指定具体输出,则默认为,否则输出到-o后面的文本中。
若用-s *.c命令,则遍历得到的符合条件文本,分别输出各文本的指定输出,如字符,单词,行数等。
4.程序设计实现过程
由于思路是从基本功能出发,进而为扩展功能,故我的程序只有一个类,这个类包含了一个主函数,其他单个功能 -c -w -l -s -a -e 分别在单个函数实现,对应函数命名为:
统计字符数 countCharacters, 统计单词数 countWords ,统计所有行数 countLines ,读取给定目录下的符合条件的文本 readAllFile, 统计给定文本的代码行,空行,注释行 countDLines , 统计除停用文本的单词外其它所有单词总数countWordsS.
函数 countCharacters,countWords,countLines实现:
.html
单词定义为用逗号或空格隔开的,非仅为英文字母组成的,如{ ,}算两个单词,//也算单词。
采取BufferedReader 读取文件,用br.read()函数并用int类型接收该函数返回的数值,返回值是否等于-1判断是否读到文件末尾,
当未读到尾部时,对读取的字符进行判断,当为单词间的空格或逗号时,字符加1,单词加1,当为换行符,单词数,行数分别进行加1,若出现连续的空格且空格不在单词间则跳过,不计入字符数,无意义。
同时对于read函数,经调用发现读取文本最后一行回车换行并另起一行空格,最后才读到-1,文件末尾,故对于此种情况跳过,不能对行数进行加1.
函数countDLines实现:
若空行{或一个字母位置或代码行在注释行内,则此行仅属于注释行,不计入代码行和空行。
对于代码行,空行,注释行判断,定义一个大小为3的数组,利用readline()函数读取一行字符串内容,当读取的内容长度不超过1时,空行加1,当读取的内容以“//”为开始startsWith(),进行注释行加1,当读取的内容以“/*”开始,"*/"结束endsWith(),计算该注释包含的所有行,其他均为代码行。
函数countWordsS实现:
.html
对于除停用词外的单词计数实现,读取源文件和停用文件的字符内容,分别提取对于文本的单词(split()+正则表达式)存到字符串数组,定义可动态增长的数组,遍历源文件,将源文件存到动态数组中,并将其转换成map<String,Integer>数据结构,便于计算单词数,对于停用词动态数组,进行遍历,若map集合键含有该单词,将其从map集合移除,最后遍历map统计得到的单词总数。
函数readAllFile实现:
.html
遍历指定格式的文本 实现:对传入的文本进行判断,若为文件目录,继续遍历该目录下的子目录包括文本,若为文本且符合指定格式,则将其添加到存放文件名的动态数组。最后返回得到的存放指定目录下或子目录下的符合格式的文本文件。
5.代码说明
关键代码:
sourceFile为符合条件的文件数组
cflag,wflag,aflag,lfag初始定义为false,当键盘输入的是-c 则cflag置为true,同理对-w -l -a。
遍历从readAllFile得到的文件,根据从键盘输入的字符判断是否需要统计字符数,单词数,总行数,还是代码行/空行/注释行。
因为需求给定输出的内容和输入顺序无关,输出的顺序均为字符-->单词-->行数-->代码行数/空行数/注释行的顺序,依次分行显示,
故文本输出时按照打印输出顺序判断,确保输出到文本的顺序。
当采用 -e命令则不统计停用表中单词,则选用countWordsS函数输出单词数,否则看是否有 -w 命令有则输出总单词数。
while(j<sourceFile.length){name=sourceFile[j].getName();if(eflag){str1=name+", 单词数: "+countWordsS(sourceFile[j], stopFile);bw.write(str1+"rn");}if(cflag){str1=name+", 字符数: "+countCharacters(sourceFile[j]);bw.write(str1+"rn");}if(!eflag&&wflag){str1=name+", 单词数: "+countWords(sourceFile[j]);bw.write(str1+"rn");} if(lflag){str1=name+", 行数: "+countLines(sourceFile[j]);bw.write(str1+"rn");}//注释行代码行空行if(aflag){str1=name+", 代码行/空行/注释行: ";int[] lines=countDLines(sourceFile[j]);str1+=""+lines[0]+"/"+lines[1]+"/"+lines[2];bw.write(str1+"rn");}j++;}
6.测试设计过程
关于测试,我选择了以下测试方案:
(1)对同一命令行采取对多个具有不同内容的文本测试,且文本写入的内容具有程序针对性。
(2)对同一文本采取多个命令行随机测试。
(3)根据程序给定的需求进行多组测试。
(4)对程序其他方面异常测试,如文件路径不存在和用户恶意输入测试等。
如下选择了较为典型的测试用例:
需求功能测试:
测试命令:
基本功能:
1) -c -w -l f:c.txt
测试文本:磁盘F路径下的c.txt
#$Vs w int main,thisprintf
输出文本:未指定则为
<,字符数:25 c.txt,单词数:6 c.txt,行数:42) 基本命令: -c -w -l file1.c -
测试文本:
file1.c
int main { return } // /**/
输出文本
file1.c,字符数:22 file1.c,单词数:7 file1.c,行数:6
扩展功能:
3) 测试命令:-l -s *.c -w -
测试文本内容:
源文本:
file.c
int main { return } // /* int main() a */
file1.c
int main {
int a=1;return } // /**/
停用词文本
int main
输出文件:默认
file.c,单词数:8 file.c,行数:9 file1.c,单词数:6 file1.c,行数:7
4) 测试命令: -l -c -a wordCount.c -
测试文本内容: wordCount.c
#include <stdio.h> //主函数 /*int a() {int b=1; } */ int main() {printf ("hello");return 0; }//函数结束
输出文本
wordCount.c,字符数:88 wordCount.c,行数:12 wordCount.c,代码行/空行/注释行:4/3/7
5) 测试命令:-s -l -c -w *.c - - -a
符合条件的测试文本:
file.c
int main { return } // /* int main() a */
file1.c
int main { return } // /**/
停用词文本
int main
输出文本
file.c,字符数:33 file.c,单词数:11 file.c,行数:9 file.c,代码行/空行/注释行:2/3/5 file1.c,字符数:22 file1.c,单词数:5 file1.c,行数:6 file1.c,代码行/空行/注释行:2/2/2
非需求测试:
6) 安全测试:
对不存在的文本进行测试
-c file.o
输出:文件或路径不存在
---------------------------------------------------------------------------------
单元测试代码:
public class WordCountTest extends TestCase{File file=null; File sourceFile=null; //源文件File stopFile=null; //停用文本int actual=0; //存放统计单词数或字符数行数int[] actuals=new int [3]; //存放统计代码行空行注释行的数量 int expected=0; //存放统计单词数或字符数行数int[] expecteds=new int [3]; //存放统计代码行空行注释行的数量ArrayList<String> filePath=new ArrayList<String>();//测试统计字符数函数public void testCharacter() throws FileNotFoundException, IOException {file=new File("file.c");actualuntCharacters( file);expected=33;assertEquals(expected, actual);}// 测试统计单词数函数public void testWord() throws FileNotFoundException, IOException {file=new File("file.c");actual = untWords(file);expected=10;assertEquals(expected, actual);}// 测试统计行数函数public void testLine() throws FileNotFoundException, IOException {file=new File("file.c");actual = untLines(file);expected=9;assertEquals(expected, actual);}// 测试统计代码行,空行,注释行数函数public void testDLine() throws FileNotFoundException, IOException {file=new File("wordCount.c");actuals = untDLines(file);expecteds[0]=4;expecteds[1]=1;expecteds[2]=7;assertArrayEquals(expecteds, actuals);}// 测试采用停用文本后统计单词数函数public void testEStop() throws Exception {sourceFile=new File("wordCount.c");stopFile=new File(");actual = untWordsS(sourceFile, stopFile);expected=8;assertEquals(expected, actual);}}
程序集成测试:
//测试程序功能 修改参数args内容
public class testMain extends TestCase{String[] args=null;File actual=null; //实际运行结果文件File expected=null; //测试前将正确的结果存入expected文件//有效等价类测试public void test1() throws Exception{args=new String[2];args[0]="-c";args[1]="wordCount.c";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}public void test2() throws Exception{args=new String[2];args[0]="-w";args[1]="wordCount.c";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}public void test3() throws Exception{args=new String[2];args[0]="-l";args[1]="wordCount.c";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}public void test4() throws Exception{args=new String[2];args[0]="-a";args[1]="wordCount.c";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}public void test5() throws Exception{args=new String[2];args[0]="-s";args[1]="wordCount.c";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}public void test6() throws Exception{args=new String[4];args[0]="-c";args[1]="wordCount.c";args[2]="-o";args[3]=";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}//基础功能综合测试public void test7() throws Exception{args=new String[4];args[0]="-w";args[1]="wordCount.c";args[2]="-c";args[3]="-l";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}//拓展功能综合测试public void test8() throws Exception{args=new String[5];args[0]="-s";args[1]="-e";args[2]=";args[3]="wordCount.c";args[4]="-a";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}//基础加拓展功能综合测试public void test9() throws Exception{args=new String[8];args[0]="-w";args[1]="wordCount.c";args[2]="-c";args[3]="-l";args[4]="-s";args[5]="-e";args[6]=";args[7]="-a";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}//基础加拓展加输出测试public void test10() throws Exception{args=new String[10];args[0]="-s";args[1]="-e";args[2]=";args[3]="wordCount.c";args[4]="-a";args[5]="-w";args[6]="-c";args[7]="-l";args[8]="-o";args[9]=";wordCount.main(args);actual=new File(");expected=new File(");assertEquals(expected, actual);}
}
---------------------------------------------------------------------------------------
7.参考文献链接
[1]:.html
[2]:.html
[3]:.html
[4]:.html
[5]:
转载于:.html
本文发布于:2024-01-29 17:35:03,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170652090417117.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |