个人项目作业——wc.exe

个人项目作业——wc.exe

1.Github项目地址:

https://github.com/Vicky-Leung/wc.exe

 

2.PSP表格:

PSP2.1 Personal Softwear Process Stages

预估耗时

(分钟)

实际耗时

(分钟)

Planning 计划 20 20
Estimate 估计这个任务需要多少时间 10 10
Development 开发 240 240
Analysis 需求分析(包括学习新技术) 120 240
Design Spec 生成设计文档 20 20
Design Review 设计复审 0 0
Coding Standard 代码规范 10 10
Design 具体设计 60 60
Coding 具体编码 60 60
Code Review 代码复审 60 60
Test 测试 30 60
Reporting 报告 30 30
Test Report 测试报告 30 30
Size Measurement 计算工作量 10 10
Postmortem&Process Improvement Plan 事后总结,并提出过程改进计划 30 30
 

合计

730 880

 

3.解题思路:

  • 语言选择:C语言,虽然说其实用C++,C#,java做这个设计会简单一些,没那么乱,但可惜我不会啊,于是便选择了C语言
  • 因为是要打开文件,对文件内容进行阅读的,所以先想到的是用fopen打开指定路径下的文件,用fgetc进行阅读
  • 递归函数这边因为要用到文件的信息,涉及_finddata_t file结构体

 

4.设计实现过程:

  • 先设置一个主函数,利用主函数调用各个功能
  • 基本功能

     -c  //返回文件 file.c 的字符数 
     -w    //返回文件 file.c 的词的数目  
     -l      //返回文件 file.c 的行数

  • 扩展功能

    -s 参数  //递归处理目录下符合条件的文件。(有bug)
    -a 参数  //返回更复杂的数据(代码行 / 空行 / 注释行)(未完成)

  • 高级功能(未完成)

    基本的Windows GUI 程序操作
    支持通过图形界面选取文件
    支持通过图形界面展现文件的信息

 

5.代码说明:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <io.h>
 5 #include<Windows.h>  
 6 #define OK     1
 7 
 8 
 9 /*----------主函数----------*/
10 int main(){
11     char ask[10],fname[100];    //ask记录功能,fname记录文件名
12     attention();    //引用注释函数
13     while(1){
14         
15         printf("\n请输入功能请求:wc.exe-");
16         scanf("%s",&ask);
17         
18         if(ask[0]=='c'){    //统计字符数
19            printf("请输入文件路径及文件名:");
20            scanf("%s",&fname);
21            int charnum=0;
22            charnum=Cnum(fname);
23            printf("文件的字符数为:%d\n",charnum);
24            continue;    
25         }
26         
27         else if(ask[0]=='w'){    //统计词的数目 
28            printf("请输入文件路径及文件名:");
29            scanf("%s",&fname);
30            int wordnum=0;
31            wordnum=Wnum(fname);
32            printf("文件的单词数为:%d\n",wordnum);
33            continue;    
34         }
35         
36         else if(ask[0]=='l'){    //统计行数 
37            printf("请输入文件路径及文件名:");
38            scanf("%s",&fname);
39            int linenum=0;
40            linenum=Lnum(fname);
41            printf("文件的行数为:%d\n",linenum);
42            continue;    
43         }        
44         
45         else if(ask[0]=='s'){    //递归处理目录下符合条件的文件
46         char add[200];    //add用于记录文件夹地址
47         char type[10];    //typ用于记录文件类型
48         printf("\n请输入文件夹路径:");
49         scanf("%s",&add);    /*    add=C:\Users\jennifer\Desktop\软工2    */
50         printf("\n请输入需要提取的文件类型:*.");
51         scanf("%s",&type);    /*    type=c    */    
52         find(add,type);
53         continue;    
54         }        
55         
56       /*  else if(ask[0]=='a'){    //返回更复杂的数据(代码行 / 空行 / 注释行)
57            printf("请请输入文件路径及文件名:");
58            scanf("%s",&fname);
59            more(fname);
60            continue;    
61         }        (未完成)*/
62         
63         else if(ask[0]=='0'){    //退出程序 
64             printf("感谢您使用本程序!\n"); 
65            exit(0);
66         }                        
67             
68         else{    //输入错误 
69             printf("请以正确的格式输入!");   
70             continue;
71         }    
72         
73     }//end while
74     return 0;
75 }//end main
 1 int attention(){    /*注释函数*/
 2 printf("\n");
 3 printf("基本功能列表: \n");
 4 printf("输入'c':返回文件 file.c 的字符数\n");
 5 printf("输入'w':返回文件 file.c 的词的数目\n");
 6 printf("输入'l':返回文件 file.c 的行数\n");
 7 printf("输入's':递归处理目录下符合条件的文件\n");
 8 //printf("输入'a':返回更复杂的数据(代码行 / 空行 / 注释行)\n");
 9 printf("输入'0':退出程序\n");
10 return OK;
11 }
 1 int Cnum(char file_name[]){        /*字符数统计函数 */
 2     FILE *fp=NULL;
 3     int cnum=0;
 4     fp=fopen(file_name,"r");
 5     if(fp==NULL){
 6         printf("查找文件失败\n");
 7     }
 8     char current_char;
 9     current_char = fgetc(fp);
10     while(current_char!=EOF){
11         current_char = fgetc(fp);
12         cnum++;
13     }
14     fclose(fp);
15     return cnum;
16 }
 1 int Wnum(char file_name[]){        /*单词数目统计函数 */
 2     FILE *fp=NULL;
 3     int wnum=0;
 4     fp=fopen(file_name,"r");
 5     if(fp==NULL){
 6         printf("查找文件失败\n");
 7     }
 8     char current_char;
 9     current_char = fgetc(fp);
10     while(current_char!=EOF){
11         if(current_char>='a'&&current_char<='z'||current_char>='A'&&current_char<='Z'||current_char=='_') {        
12             while(current_char>='a'&&current_char<='z'||current_char>='A'&&current_char<='Z'||current_char=='_'){
13                 current_char=fgetc(fp);        //光标在单词内部后移 
14             }//end while 结束while意味着光标已经走完了这个单词 
15         wnum++;     
16         }//end if  记录个数加一
17         current_char=fgetc(fp);        
18     }//end while
19     fclose(fp);
20     return wnum;
21 }
 1 int Lnum(char file_name[]){        /*行数统计函数 */
 2     FILE *fp=NULL;
 3     int lnum=0;
 4     fp=fopen(file_name,"r");
 5     if(fp==NULL){
 6         printf("查找文件失败\n");
 7     }
 8     char current_char;
 9     current_char = fgetc(fp);
10     while(current_char!=EOF){
11         if(current_char=='\n')
12             lnum++;
13         current_char = fgetc(fp);            
14     }
15     fclose(fp);
16     lnum++;
17     return lnum;
18 }
 1 int find(char *path,char *type)            /*递归函数 (有bug)*/
 2 {                            /*    path=C:\Users\jennifer\Desktop\软工2        */
 3     char now_path[200];
 4     char file_path[200];    
 5     strcpy(now_path,path);
 6     strcpy(file_path,path);    
 7     strcat(path,"\\");        /*    path=C:\Users\jennifer\Desktop\软工2\    */
 8     strcat(file_path,"\\*.");    
 9     strcat(file_path,type);    /*    file_path=C:\Users\jennifer\Desktop\软工2\*.c*/
10     strcat(now_path,"\\*.*");/*    path=C:\Users\jennifer\Desktop\软工2\*.*    */    
11         
12             
13     struct _finddata_t file;    
14     long handle;    
15     
16      handle=_findfirst(file_path,&file);        
17     if (handle == -1)
18         return -1;
19     else {
20         do {
21                 if(file.attrib != _A_SUBDIR){
22                     printf("%s%s\n",path,file.name);    //输出文件名                     
23                 }
24         } while (_findnext(handle, &file) == 0);
25     }
26     _findclose(handle);
27     
28     char next_path[200];
29     handle=_findfirst(now_path,&file);    
30     if (handle == -1)
31         return -1;
32     else {
33         do {
34             if(file.attrib == _A_SUBDIR && 
35             strcmp(file.name, ".") && strcmp(file.name, "..") ){
36             //    printf("%s%s\n",path,file.name);    //输出文件夹名 
37                 strcpy(next_path,path);
38                 strcat(next_path,file.name);
39                 find(next_path,type);    //递归 
40             }    
41         } while (_findnext(handle, &file) == 0);
42     }
43     _findclose(handle);        
44     
45 }

 

6.测试运行:

关于基本功能,这里用C:\Users\jennifer\Desktop\软工2\code.c进行测试

code.c内容如图:

 

与wc.exe的基本功能运行结果如图:

 

接下来是-s功能,设置路径为C:\Users\jennifer\Desktop\软工2,命令为搜索所有文件,经校对,结果显示正确

 

 但这个代码有bug,当我指定文件后缀为*.c时,结果显示与预期不符,程序无法读取新建文件夹3下的cccc.c文件

 

 

输入错误时,如图

 

 

最后,输入0结束使用程序

 

 

 

7.项目小结:

1.要肯在需求分析和项目进程规划方面下功夫,需求分析和项目规划做得马虎,有过多漏洞的话,后续写代码的时候发现一开始思路有误的话,很容易浪费大量的时间去重新整改思路,回去修改原已写好的代码,越是这样,整个项目下来就会越乱,代码可读性也会有所降低,最后项目所用时间也会比预期要多很多。

2.知识储备真的很重要,在写这个项目的过程中,我大部分时间都是在查资料的,比如说_finddata_t file结构体,我两个晚上的时间都是在查这个结构体,去看应该怎么使用它,很遗憾的是,我还是没能学会它,导致我的递归函数出现了bug,这个bug修改了很久依旧无果,还是要把知识点吃透一点才行。

3.关于-a扩展功能,本来是打算写一个名叫more的函数,函数里面先调用行数统计函数得到line_count,然后计算空行行数empty_count,计算注释行数note_count,再用line_count减去empty_count减去note_count得到代码行code_count的,但是写的时候在注释块这边卡住了,并且后来发现,不能用减的方法得到代码行,因为有可能一行里面,它既是代码行又是注释行,所以最后这个功能也就没实现了

4.通过这次的项目,认识到自己有很多很多不足,还是要多多学习,努力提升自己呀!

posted @ 2020-03-15 23:57  VickyLeung  阅读(140)  评论(0)    收藏  举报