WordCount的实现和测试

 

WordCount

一、开头

(1)合作者:201631107110,201631083416

(2)代码地址:https://gitee.com/zhaoxiaoqin/WordCount.git

(3)本次作业链接地址:https://www.cnblogs.com/zhaoxiaoqin/articles/9824449

二、正文

1.项目完成情况:

1.1 基本功能(完成)

wc.exe -c input.c     //返回文件 file.c 的字符数

wc.exe -w  input.c     //返回文件 file.c 的单词总数

wc.exe -l input.c     //返回文件 file.c 的总行数

1.2 扩展功能(未完成)

wc.exe -s            //递归处理目录下符合条件的文件

wc.exe -a  input.c     //返回更复杂的数据(代码行 / 空行 / 注释行)

wc.exe -e stopList.txt  // 停用词表,统计文件单词总数时,不统计该表中的单词

[file_name]: 文件或目录名,可以处理一般通配符

2.实现代码

 2.1 main函数实现参数传递

1 int main(int argc, char* argv[]) {
2     Test(argc, argv);//测试
3     getchar();
4     return 0;
5 }

2.2 GetOption函数实现参数解析

 1 int *GetOptions(int argc,char* argv[])
 2 {
 3     /* 返回0代表参数有错
 4      *  1 表示读取字母
 5      * 3 表示读取单词
 6      *  5 表示读取行数
 7      *  它们的和代表所要的功能
 8      */
 9 
10     char* params;
11     for(int i=0;i<argc;i++)
12     {
13         params = argv[i];
14         if(strcmp("-c",params) == 0)
15         {
16             ret[0] += 1;
17         }
18         else if(strcmp("-w",params) == 0)
19         {
20             ret[0] += 3;
21         }
22         else if(strcmp("-l",params) == 0)
23         {
24             ret[0] += 5;
25         }
26         //启动图形界面,则退出命令行结口
27 
28     }
29     if(argc > 3) {
30         params = argv[argc - 2];
31         if (strcmp("-o", params) == 0 && argv[argc - 1] != NULL) {
32             result = argv[argc - 1];
33             ret[1] = argc - 3;
34         }
35         else
36         {
37             ret[1]= argc - 1;
38         }
39     }else {
40         ret[1] = argc - 1;
41     }
42     //处理 -o之前缺少输入文件
43     return  ret;
44 }

2.3 WordCount函数根据解析的参数执行相应操作

 1 void WordCount(int argc,char* argv[])
 2 {
 3     list = createlist();//创建单词列表
 4     char* fileName;
 5     if (argc <= 1) {
 6         Help();
 7         exit(0);
 8     }
 9     GetOptions(argc,argv);
10     fileName = argv[ret[1]];
11     switch(ret[0])
12     {
13         case 1:
14             ReadChar(fileName);
15             break;
16         case 3:
17             ReadWord(fileName);
18             break;
19         case 5:
20             Readlines(fileName);
21             break;
22         case 4: {
23             ReadChar(fileName);
24             flag = 1;
25             ReadWord(fileName);
26             break;
27         }
28         case 6: {
29             ReadChar(fileName);
30             flag = 1;
31             Readlines(fileName);
32             break;
33         }
34         case 8:{
35             ReadWord(fileName);
36             flag = 1;
37             Readlines(fileName);
38             break;
39         }
40         case 9: {
41             CharWordLine(fileName);
42             break;
43         }
44         default:
45             Help();
46             break;
47     }
48 }

2.4 ReadChar函数实现对文件的字符统计

 1 void *ReadChar(char* fileName)
 2 {
 3     char* feature = "字符数: ";
 4     char buf;
 5     //int count[1] = {0}; //用来储存字母出现过的次数
 6     int sum = 0;
 7     FILE* fp = fopen(fileName,"r");
 8     if (fp == NULL)
 9     {
10         printf("Fail to open the file!\n");
11         Help();
12         exit(-1);
13     }
14     while(!feof(fp))
15     {
16         buf = fgetc(fp);
17         sum ++;
18     }
19     fclose(fp);
20     int count[1] = {sum};
21     WriteToFile(fileName,count,1,feature);
22     print(fileName, count, 1, feature);
23 }

2.5 ReadWord实现对文件的单词统计

 1 void *ReadWord(char* fileName)
 2 {
 3     /*在记录单词个数 的时候,
 4     * 我们通过统计逗号和空格的个数
 5     * 然后通过计算得到单词的个数
 6      * 假设每个单词的长度不超过256字母
 7     */
 8     
 9     char *feature = "单词数:";
10     getwordCount(fileName);//得到文件的单词统计
11     printword();
12     int sum = 0;
13     for (int i = 0; i < list.count; i++)
14         sum += list.list[i].count;//计算总量
15     int count[1] = { sum };
16     WriteToFile(fileName, count, 1, feature);
17     return NULL;
18 }

2.6 ReadLine 实现对文件行数的统计

 1 void *Readlines(char* fileName)
 2 {
 3     char buf = '\0';
 4     char* feature  = "行数: ";
 5     FILE* fp = NULL;
 6     fp = fopen(fileName,"r");
 7     if (fp == NULL)
 8     {
 9         printf("Fail to open the file!\n");
10         Help();
11         exit(-1);
12     }
13     int space[1] = {0}; //记录行数
14     while(!feof(fp))
15     {
16         buf = fgetc(fp);
17         if (buf == 10)  //换行符的ASCII码为10 只要找出所有的换行符就好
18         {
19             space[0] ++;
20         }
21     }
22     space[0] ++; //在最后一个行中会把换行符设置为其他字符,随意需要加1
23     WriteToFile(fileName,space,1,feature);
24     print(fileName, space, 1, feature);
25     //关闭文件
26     fclose(fp);
27 }

2.7 WriteToFile函数实现将统计信息存入文件中

 1 void WriteToFile(char* fileName,int count[],int Csize,char* feature)
 2 {
 3     /*fileName 表示读取的文件
 4      * count 表示记录的个数
 5      * Csize 表示记录数组的大小
 6      * feature表示记录的内容 单词或者字母或者行数
 7      * flag 表示只写,还是追加模式,0 表示只写,1表示追加
 8      */
 9     char *mode = '\0';
10     if (flag == 1)
11     {
12         mode = "a+";
13     }
14     else
15     {
16         mode = "w+";
17     }
18     int index = 0; //记录字符数
19     for(int i=0;i<Csize;i++)
20     {
21         if(count[i] != 0)
22         {
23             index += count[i];     //计算总的单词个数
24         }
25     }
26     FILE *fp = NULL;
27     fp = fopen(result,mode); //将结果写入文件
28     if (fp == NULL)
29     {
30         printf("Failed when writing the count to file\n");
31         exit(-1);
32     }
33     fprintf(fp,"%s,%s %d\n",fileName,feature,index); //写入文件
34     
35     if (list.count > 0)
36     {
37         for (int i = 0; i < list.count; i++)
38         {
39             fprintf(fp, "%s:%d\n", list.list[i].wordstring, list.list[i].count); //写入文件
40         }
41     }
42     fclose(fp);
43 }

2.8 getwordCount函数实现对文件中各单词的分离和统计

 1 void getwordCount(char *filename)//得到各单词的个数统计
 2 {
 3         char data[100];//假设每行最多100个字符
 4         FILE* fp = NULL;
 5         fp = fopen(filename, "r");
 6         if (fp == NULL)
 7         {
 8             printf("Fail to open the file!\n");
 9             Help();
10             getchar();
11             exit(-1);
12         }
13         while (!feof(fp))
14         {
15             fscanf(fp, "%s", &data);
16             char str[n];
17             for (int i = 0; i < n; i++)
18             {
19                 str[i] = '\0';
20             }
21             int len = 0;
22             for (int i = 0; i < strlen(data); i++)
23             {
24                 char c = data[i];
25                 if (!issplitchar(c))//若不为单词分隔符
26                 {
27                     str[len] = c;
28                     
29                     len++;
30                 }
31                 else//若为单词分隔符且指针不超过字符长度
32                 {
33                     if (len > 0)
34                     {
35                         additem(&list, str);//添加
36                     }
37 
38                     for (int i = 0; i < n; i++)
39                     {
40                         str[i] = '\0';
41                     }
42                     len = 0;
43                 }
44             }
45             if (len > 0)
46             {
47                 additem(&list, str);//添加
48             }
49         }
50         fclose(fp);
51 
52 }

2.9 word和wordlist结构体用于保存单词和单词的个数

 1 typedef struct word//保存单词信息
 2 {
 3     char* wordstring;//内容
 4     int count;//数量
 5 }word;
 6 
 7 typedef struct wordlist//单词列表定义
 8 {
 9     word *list;//单词列表
10     int count;//单词种类个数
11 }wordlist;

3.互审代码情况

参数 功能
-w 统计文件中的单词个数以及各单词的个数并写入输出文件中
-l 统计文件的行数并写入输出文件中
-c 统计文件中的字符个数并写入输出文件中
-o 文件的路径

 

 

 

 

 

 

 

已完成WordCount的基本功能,包括字符计数、行数计数、单词统计等,但在单词统计和行数统计同时存在时,输出文件中的行数会写错位,该版本的WordCount可以接收多个参数,比如-w -c -l等,可以同时存在,而-w参数可以统计文本文件中的各单词的个数并将其保存在输出文件中。

4.静态代码检查情况

利用VisualStudio自带的静态代码检测工具对项目进行代码检测后,结果如下:

在对出现的风险代码进行修改后,对项目进行测试。

5.测试

 5.1 测试用例

用例编号 输入 输出 测试结果
1 WordCount.exe -c text.txt 文件字符数:726 通过
2 WordCount.exe -l text.txt 文件行数:8 通过
3 WordCount.exe -w text.txt

单词种类数:80
单词总量:108

通过
4

WordCount.exe -c -l text.txt

文件字符数: :736
文件行数: :8

 
 通过

5

WordCount.exe -c -l -w text.txt  

文件字符数: :736
单词种类数:80
单词总量:108

文件行数:8

 通过

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.2 测试

测试用例1

测试用例2

 

测试用例3

测试用例4

 

测试用例5

 

 6.总结

       在对项目进行了一系列测试后,发现该项目不存在较大bug,在输入命令参数时,若输入了不合规则的参数,程序会输出提示字符串,但其中的单词统计不能统计诸如I_ptr等带有下划线的单词,可以在后期的改进中,改良分隔字符串检测的算法,该项目的总体思路为:用户在输入参数后,通过main函数的参数传递,将参数传递到GetOption函数中,GetOption函数通过输入参数的个数和种类来解析用户想要执行的命令,并将命令传递到WordCount函数中,对文件执行相应的操作,而在单词统计模块中,该项目自定义了一个结构体来保存单词的字符串和出现次数,当统计函数对文件进行扫描时,每当扫描出一个单词便判断该单词是否在单词列表中,若不在单词列表中则将该单词添加,若在单词列表中则将该单词的次数加1,从而实现了对文件中不同单词的分隔和个数统计。

 

posted @ 2018-10-21 16:31  清风竹间行  阅读(858)  评论(0编辑  收藏  举报