Github地址:https://github.com/cfafa2018/WordCount
队友博客地址:http://www.cnblogs.com/quinnqz/
时间安排:
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
|
|
·Estimate |
·估计这个任务需要多少时间 |
30 |
30 |
Development |
开发 |
2000
|
|
·Analysis |
·需求分析(包括学习新技术) |
400 |
400 |
·Design Spec |
·生成设计文档 |
60 |
50 |
·Design Review |
·设计复审 |
30 |
30 |
·Coding Standard |
·代码规范 |
60 |
60 |
·Design |
·具体设计 |
300 |
350 |
·Coding |
·具体编码 |
850 |
1100 |
·Code Review |
·代码复审 |
70 |
60 |
·Test |
·测试 |
180 |
180 |
Reporting |
报告 |
60 |
60 |
·Test Report |
·测试报告 |
30 |
30 |
·Size Measurement |
·计算工作量 |
30 |
30 |
·Postmortem&Process Improvement Plan |
·事后总结并提出过程改进计划 |
30 |
30 |
|
合计 |
4160 |
4840
|
思路:
整个项目的具体要求是要实现一个统计程序,能够统计程序文件中的字符数、单词数、行数,以及其他的扩展功能,并且能够快速的处理整个文件。
基本功能:
1、wc.exe -c file.c //返回文件file.c中的字符数。
处理规则是:普通字符就按一个字符算,空格回车也算一个字符。因为我的编译器是Xcode,所以对汉字进行处理的时候编译器默认是按三个字符计算,所以处理的时候如果是汉字就在原有基础上减了2。但是我队友的dev是按两个字符算的,代码只减了1。所以处理的时候有一点不一样。
1 void Charcount(FILE *fp)//字符计数 2 { 3 int sum=0; 4 char str; 5 int flag = 0; 6 char temp = ' '; 7 while(fscanf(fp,"%c",&str)!=EOF) 8 { 9 sum++; 10 if (!(str >= 0 && str <= 127) && !(temp >= 0 && temp <= 127) && flag < 3) { 11 sum = sum - 1; 12 flag ++; 13 } 14 if(flag == 2){ 15 flag = 0; 16 temp = ' '; 17 } 18 else temp = str; 19 } 20 cout<<"the num of char is:" <<sum<<endl; 21 fclose(fp); 22 }
2、wc.exe -w file.c //返回文件file.c中的词的数目。
处理规则:只计算英文单词,中文及别的字符不算,英文字符只要中间有别的字符隔开就单独算一个单词,例如:stdio.h,这样算两个单词。
1 void Wordcount(FILE *fp)//单词计数 2 { 3 int sum=0; 4 char str; 5 char temp[20]={0}; 6 int flag = 0; 7 int j = 0; 8 while(fscanf(fp,"%c",&str)!=EOF) 9 { 10 if(!(str >= 'a' && str <= 'z') && !(str >= 'A' && str <= 'Z')){ 11 for (int i = 0; i < strlen(temp); i ++) { 12 if((temp[i] >= 'a' && temp[i] <= 'z') || (temp[i] >= 'A' && temp[i] <= 'Z')){ 13 flag = 1; 14 break; 15 } 16 } 17 } 18 else{ 19 temp[j] = str; 20 j ++; 21 } 22 if(flag == 1){ 23 sum ++; 24 flag = 0; 25 j = 0; 26 memset(temp, 0, sizeof(temp)); 27 } 28 } 29 cout<<"the num of word is:"<<sum<<endl; 30 fclose(fp); 31 }
3、wc.exe -l file.c //返回文件file.c中的行数。
处理规则:文件中有换行符的时候就是新的一行,和文件中的行数显示一致。这里我的编译器和队友的编译器又出现了一点不一致,同一份代码我的行数会少1,所以处理的时候最后结果加了1。
1 void Linecount(FILE *fp)//行计数 2 { 3 int sum=0; 4 char str; 5 while(fscanf(fp,"%c",&str)!=EOF) 6 { 7 if(str=='\n') 8 sum++; 9 } 10 cout<<"The num of line is:"<<sum+1<<endl; 11 fclose(fp); 12 }
扩展功能:
4、-s //递归处理目录下符合条件
处理规则:先将目录下符合条件的文件全部放到一个txt里,然后对txt里的内容进行处理。处理结果包括字符数、词数、空行数、代码行数以及注释行数。这里只处理了 .c 文件 没有对别的文件进行扩展,如果需要,可以直接在代码里修改,使之能处理更多格式的文件。
1 if(strcmp("-s",argv[1])==0) 2 { 3 char str[30][100]; 4 int i=0; 5 system("dir /B > log.txt"); 6 fp=fopen("log.txt","r"); 7 while(!feof(fp)) 8 { 9 char ch2[100]; 10 fgets(ch2,100,fp); 11 int len=strlen(ch2); 12 if(ch2[len-2]=='c' && ch2[len-3]=='.' && len>3) 13 { 14 strcpy(str[i],ch2); 15 str[i][len-1]='\0'; 16 i++; 17 } 18 } 19 int n=i; 20 for(i=0;i<n;i++) 21 { 22 FILE *f1=fopen(str[i],"r"); 23 printf("%s:\n",str[i]); 24 Charcount(f1); 25 f1=fopen(str[i],"r"); 26 Linecount(f1); 27 f1=fopen(str[i],"r"); 28 Wordcount(f1); 29 f1=fopen(str[i],"r"); 30 Count(f1); 31 32 } 33 }
5、-a //返回更复杂的数据(代码行/空行/注释行)
处理规则:空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
代码行:本行包括多于一个字符的代码。
注释行:本行不是代码行,并且本行包括注释。还有在单个字符后面加注释的行,例如:{//注释
1 void Count(FILE *fp)//返回更复杂的数据(空行/代码行/注释行) 2 { 3 int i=0,esum=0,csum=0,nsum=0; 4 char str; 5 do{ 6 if(feof(fp)) 7 break; 8 fscanf(fp,"%c",&str); 9 if((feof(fp))) 10 break; 11 while(str=='\t'||str==' ') 12 fscanf(fp,"%c",&str); 13 if(str=='\n') 14 { 15 fscanf(fp,"%c",&str); 16 i=1; 17 while(str=='\t'||str==' ') 18 fscanf(fp,"%c",&str); 19 if(str=='\n') 20 { 21 esum++; 22 i=0; 23 } 24 else if(str=='}'||str=='{') 25 { 26 fscanf(fp,"%c",&str); 27 while(str=='\t'||str==' ') 28 { 29 fscanf(fp,"%c",&str); 30 i++; 31 } 32 if(str=='\n') 33 { 34 esum++; 35 i=0; 36 } 37 else if((feof(fp))) 38 esum++; 39 else 40 { 41 fseek(fp,-i,1); 42 i=0; 43 } 44 } 45 else 46 fseek(fp,-1,1); 47 } 48 else if(str=='}'||str=='/') 49 { 50 fscanf(fp,"%c",&str); 51 while(str==' '||str=='\t') 52 fscanf(fp,"%c",&str); 53 if(str=='/'||str=='*') 54 { 55 nsum++; 56 while(str!='\n') 57 { 58 fscanf(fp,"%c",&str); 59 if(feof(fp)) 60 break; 61 } 62 if(!(feof(fp))) 63 fseek(fp,-1,1); 64 } 65 } 66 else 67 { 68 csum++; 69 while(str!='\n') 70 fscanf(fp,"%c",&str); 71 fseek(fp,-1,1); 72 } 73 74 } 75 while(1); 76 cout<<"the num of empty-line is:"<<esum+1<<endl; 77 cout<<"the num of code-line is:"<<csum<<endl; 78 cout<<"the num of node-line is:"<<nsum<<endl; 79 fclose(fp); 80 }
总结:
由最开始的代码勉强正确,因为处理txt文件文本的时候是正确的,但是处理程序文件就不行,所以又根据程序文件的特点进行修改,使之在我们定义的处理规则上得到正确结果。从基本功能一点一点修改,慢慢加入扩展功能,但是没有对高级功能进行实现。学到了很多东西,对于汉字的处理,不同编译器的不同之处,对文件的处理等等,收获很大。