wordCount的实现
合作者学号:201631062605, 201631062405
一本文代码
Github代码下载链接:https://github.com/OuLianhHong00/WordCount
本次作业地址:https://edu.cnblogs.com/campus/xnsy/Test/homework/2203
二:功能概述及psp:
2.1.1 基本功能(完成)
wc.exe -c file.c //返回文件 file.c 的字符数
wc.exe -w file.c //返回文件 file.c 的单词总数
wc.exe -l file.c //返回文件 file.c 的总行数
wc.exe -o outputFile.txt //将结果输出到指定文件outputFile.txt
2.1.2 扩展功能(未完成)
wc.exe -s //递归处理目录下符合条件的文件
wc.exe -a file.c //返回更复杂的数据(代码行 / 空行 / 注释行)
wc.exe -e stopList.txt // 停用词表,统计文件单词总数时,不统计该表中的单词
[file_name]: 文件或目录名,可以处理一般通配符
2.1.3 高级功能(未完成)
wc.exe -x //该参数单独使用,如果命令行有该参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、单词数、行数等全部统计信息。
2.1.4psp表格
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
三:项目设计
3.1 接受参数
参数的形式有两种:长选项、短选项,选项间可以组合,长选项用空格隔开各个参数
例: wc.exe --word --charater file.c
短选项可以多个直接叠加或者,也像长选项一样分开写
例: wc.exe -wc file.c
wc.exe -w -c file.c
对于一个命令行程序,它可以接受来自命令行的参数。
c语言的main函数中有两个参数:int main (int argc, char *argv[])
,这两个参数就是用于这个参数的输入。
argc 一个整数,代表有多少个命令行参数,在此注意两个点
1、 参数间是用空格格开的;
2、程序名是第一个参数。
argv[i]是一个指针,指向第i个参数的首地址
理解了以上的两个参数就简单了,只需要做一些基本的字符串处理就可以了。
3.1.1 -h参数
这个参数单独说是因为这个参数不能和别的参数混用,所以我在程序里面是单独写的,一开始就判断是否用户需要的是help帮助,如果是的话,那么完全不必要再运行程序(打开文件),直接exit中止进程 。
3.1.2 -w -c -l 参数
这三个参数都是一个路数:
1、打开文件;
2、判断要做的操作;
3、执行操作。
它们间只有步骤3是不同的,所以有理由把3写成不同的函数,再由2判断执行哪个。
有一些细节问题是可以考虑的。
比如,因为单复数的关系,有一行/个 单词/字母,应该是不同的表达(是否有s)
额外就是判断一个单词的算法也是值得考虑的问题,我的想法是,如果一个字符,它自己是一个字母,它前面是一个非字母,那么这就是一个单词的标致。
3.1.3 -o 参数
这个参数比较特殊,因为它后面跟了一个文件,要做的事情是把输出的内容存到的文件换成用户自定义的名字。
总的来说是两件事情
-
捕获用户输入的文件的名字,并创建这个文件;
-
把输出的信息存进去
四:代码实现
1 int main(int argc, char* argv[])//主程序 2 { 3 //计算单词数 4 int countWord(char *file); 5 //计算字符数 6 int countChar(char *file); 7 //计算行数 8 int countLine(char *file); 9 //空行 10 int count_blankLine(char *file); 11 //代码行 12 int count_codeLine(char *file); 13 //注释行 14 int count_noteLine(char *file); 15 //递归找符合条件的文件 16 void scanFile(); 17 //将内容输出到outputFile.txt文件中 18 void printFile(char *file,int result,char type); 19 int cw=0,cc=0,cl=0,cb=0,ccl=0,cn=0; 20 FILE *fp; 21 22 while(1==1){ 23 24 scanf("%s %s %s",argv[0],argv[1],argv[2]);//argv[0] 可执行程序的文件名argv[1] 指令,argv[2]文件名 25 if((fp=fopen(argv[2],"r"))==NULL){ 26 printf("文件不存在\n\n"); 27 //scanf("%s %s %s",argv[0],argv[1],argv[2]);//argv[0] 可执行程序的文件名argv[1] 指令,argv[2]文件名 28 continue; 29 } 30 else 31 { 32 if(!strcmp(argv[1],"-w"))//判断字符串是否相等 33 { 34 int cw=countWord(argv[2]); 35 36 } 37 if(!strcmp(argv[1],"-c")) 38 { 39 int cc=countChar(argv[2]); 40 41 } 42 if(!strcmp(argv[1],"-l")) 43 { 44 int cl=countLine(argv[2]); 45 46 } 47 if(!strcmp(argv[1],"-a"))//代码、空行、注释 48 { 49 int cb=count_blankLine(argv[2]); 50 int ccl=count_codeLine(argv[2]); 51 int cn=count_noteLine(argv[2]); 52 53 } 54 if(!strcmp(argv[1],"-s"))//递归目录下符合条件的文件 55 { 56 scanFile(); 57 } 58 if(!strcmp(argv[1],"-o")) 59 { 60 printFile(argv[2],cw,'w'); 61 printFile(argv[2],cc,'c'); 62 printFile(argv[2],cl,'l'); 63 printFile(argv[2],cb,'e'); 64 printFile(argv[2],ccl,'f'); 65 printFile(argv[2],cn,'g'); 66 } 67 68 } 69 70 fclose(fp); 71 } 72 return 0; 73 }
1 //计算单词数 2 int countWord(char *file) 3 { 4 FILE *fp; 5 int wCount=0; 6 int is_word=0; 7 char a; 8 fp=fopen(file,"r"); 9 if(fp==NULL){ 10 printf("文件打开失败\n"); 11 }else{ 12 while(!feof(fp)){ 13 a=fgetc(fp); 14 if((a>='a'&&a<='z')||(a>='A'&&a<='Z')||a=='_') 15 is_word=1; 16 else if(is_word){ 17 wCount++; 18 is_word=0; 19 } 20 } 21 } 22 fclose(fp); 23 printf("该文件单词数为:%d\n",wCount); 24 return wCount; 25 }
1 //计算字符数 2 int countChar(char *file) 3 { 4 FILE *fp; 5 fp=fopen(file,"r"); 6 char a; 7 int cCount=0; 8 if(NULL==fp) 9 { 10 printf("文件为空\n"); 11 }else{ 12 while((a=fgetc(fp))!=EOF){ 13 cCount++; 14 } 15 } 16 fclose(fp); 17 printf("字符数为:%d\n",cCount); 18 return cCount; 19 }
//计算行数 int countLine(char *file) { FILE *fp; fp=fopen(file,"r"); int lCount=0; char a; if(NULL==fp) { printf("文件为空\n"); }else{ while((a=fgetc(fp))!=EOF){ if(a=='\n') lCount++; } } fclose(fp); printf("文件总行数为:%d\n",lCount); return lCount; }
1 //空行 2 int count_blankLine(char *file) 3 { 4 FILE *f; 5 int blCount= 0; 6 int ch_num = 0; 7 char ch; 8 f = fopen(file, "r"); 9 if(NULL==(f=fopen(file,"r"))) 10 { 11 printf("文件为空"); 12 } 13 else 14 while (!feof(f)) 15 { 16 ch= fgetc(f); 17 if (ch=='\n'){ 18 if (ch_num<= 1) 19 blCount++; 20 ch_num = 0; 21 } 22 else if (ch!=' '&&ch!='\t') 23 ch_num++; 24 } 25 fclose(f); 26 printf("文件空行为:%d\n ",blCount); 27 return blCount; 28 }
1 //代码行 2 int count_codeLine(char *file) 3 { 4 FILE *fp; 5 fp=fopen(file,"r"); 6 int clCount=0; 7 char a; 8 if(NULL==fp) 9 { 10 printf("文件为空\n"); 11 }else{ 12 while((a=fgetc(fp))!=EOF){ 13 if(a==';') 14 clCount++; 15 } 16 } 17 fclose(fp); 18 printf("文件代码行数为:%d\n",clCount); 19 return clCount; 20 }
1 //注释行 2 int count_noteLine(char *file) 3 { 4 FILE *f; 5 int ch_num = 0; 6 int nlCount=0; 7 char ch; 8 f=fopen(file, "r"); 9 if(NULL==(f=fopen(file,"r"))) 10 { 11 printf("文件为空\n"); 12 } 13 else 14 while (!feof(f)) 15 { 16 ch= fgetc(f); 17 if(ch=='\n') 18 { 19 if(ch_num==2) 20 nlCount++; 21 ch_num=0; 22 } 23 else if(ch=='/') 24 ch_num++; 25 else if(ch_num==1) 26 { 27 if(ch=='/') 28 ch_num++; 29 } 30 } 31 fclose(f); 32 printf("文件注释行为:%d\n ",nlCount); 33 return nlCount; 34 }
//递归找符合条件的文件 void scanFile() { printf("you"); } void printFile(char *file,int result,char type){ FILE *wp; if((wp=fopen("outputFile.txt","a"))==NULL){ printf("文件不存在\n\n"); }else{ switch(type){ case 'c': fprintf(wp, "%s文件中字符数有%d", file,result); break; case 'w':fscanf(wp, "%s文件中单词数有%d", file,result); fprintf(wp, "%s文件中单词数有%d", file,result); break; case 'l': fprintf(wp, "%s文件中总行数数有%d", file,result); break; case 'f': fprintf(wp, "%s文件中代码行数有%d", file,result); break; case 'e': fprintf(wp, "%s文件中空行数有%d", file,result); break; case 'g': fprintf(wp, "%s文件中注释数有%d", file,result);break; default:; break; } } fclose(wp); }
五:测试用例
等价类划分
输入
读取文件的命令 |
有效等价类
1. -w 2. -l 3. -c 4. -w -l -c 5. -w -l 6. -w -c 7 -l -c 8 空 |
无效等价类
9.除了-w -c -l 之外的其余任何输入参数 |
结果写入参数 | 10. -o |
11.其他输入 |
文件名 | 12.正确文件名 | 13 非文件名 |
基于等价类划分的测试用例设计:
测试用例 | 作用 |
1 wc.exe -l -w -c test.txt | 测试文件中有多少字符数,行数,单词数 |
有效测试
2.wc.exe -c outputFile.txt | 测试outputFile.txt字符数 |
3.wc.exe -w test.txt | 测试文件单词总数 |
4.wc.exe -l test.txt | 表示返回文件file.c的总行数,并存储在result.txt |
5wc.exe -o test.txt | 表示返回文件file.c的总行数,并存储在result.txt |
6.wc.exe -l -w -c test.txt -o outputFile.txt, | 都覆盖 |
7.wc.exe -s test.txt | 遍历文件夹参数 |
8.wc.exe -l -w test.txt | 遍历文件中的字符数,行数 |
9.wc.exe -w -c test.txt | 遍历文件中的行数和单词数 |
10. wc.exe -l -c test.txt | 遍历文件中的字符数和单词数 |
注:-s暂不能使用 |
六:单元执行结果
6.1测试的文件内容:
6.2执行结果
七可视化界面
八:优化
8。1测试数据集思路:
选用所有单元测试中的等价类和无效等价类进行进行测试,然后将各模块进行联合测试。
九:总结与收获
经过这次wordCount的测试设计与实现,掌握了等价类划分等测试方法,掌握了cmd 的一系列使用命令,通过与小伙伴一起实现wordCount的测试项目。了解了软件测试对于软件开发的重要性,测试的目的是为了发现尽可能多的缺陷,不是为了说明软件中没有缺陷。本次主要是对wordCount的单元测试,利用白盒测试法,在已经知道所测试的文件的内容,以及代码结构的基础上来进行的测试,主要是测试基本功能是否得到了实现以及一些逻辑分支是否正确,面对错误的边界值等,程序的主要处理方式。