Word Count

Github地址:https://github.com/mk-god/WC

一、项目要求

wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。

实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:
程序处理用户需求的模式为:

wc.exe [parameter] [file_name]

基本功能列表:

wc.exe -c file.c //返回文件 file.c 的字符数 (实现)

wc.exe -w file.c //返回文件 file.c 的词的数目 (实现)

wc.exe -l file.c //返回文件 file.c 的行数 (实现)

扩展功能:
-s 递归处理目录下符合条件的文件(未实现)
-a 返回更复杂的数据 (实现)

二、PSP表

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

15

15 

· Estimate

· 估计这个任务需要多少时间

15

15

Development

开发

360

400

· Analysis

· 需求分析 (包括学习新技术)

 30

40

· Design Spec

· 生成设计文档

 10

10 

· Design Review

· 设计复审 (和同事审核设计文档)

 

 

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 10

10

· Design

· 具体设计

20

10 

· Coding

· 具体编码

240

220

· Code Review

· 代码复审

10 

20 

· Test

· 测试(自我测试,修改代码,提交修改)

40

90 

Reporting

报告

 30

30

· Test Report

· 测试报告

 10

10 

· Size Measurement

· 计算工作量

 10

10 

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 10

10 

合计

 

 405

 445

 

三、解题思路

  • 对于其他语言掌握不是很熟练所以选择了c语言来完成这次练习。
  • 自定义函数代码比较简单,主要查阅了关于文件读取操作的方法。
  • 编写了Charater函数、Word函数、Line函数、Anther函数,最后通过main函数进行调用。

四、设计实现过程

  •  设计函数有:
  1. 统计字符Charater函数
  2. 统计单词Word函数
  3. 统计行数Line函数
  4. 统计注释行/空行/代码行行数Anther函数的
  • 大致逻辑框图:

 

 

 

 

 五、代码说明

  • 统计字符数函数(Charater函数):调用fopen函数判断文件是否正确(下同),调用fgetc函数逐步读取字符(下同),满足条件则字符数增加;
 void Character(char *file)
  {
          char c;
          int num=0;
          FILE *f;
    if((f=fopen(file,"r"))==NULL)   //判断输入文件名是否正确,下同
    {
    printf("         无法打开此文件\n");
            return ;
    }
    while(c=fgetc(f)!=-1)       //读取文件
    {
             num++;
    }
    rewind(f);
    printf("         该文件字符数为:%d\n",num);
    fclose(f);
  }

 

  • 统计单词数函数(Word函数):判断读取的字符是否满足介于英文大小写26个字母,若满足条件且上一个字符不满足条件(通过a的值判断),则单词数增加;
void Word(char *file)
  {


          char c;
          int num=0;
          int a=0;
           FILE *f;
    if((f=fopen(file,"r"))==NULL)
    {
    printf("         无法打开此文件\n");
             return ;
    }
   c=fgetc(f);
   while(!feof(f)){

      c=fgetc(f);
   if(c<'A'||(('Z'<c)&&(c<'a'))||c>'z')   //
      a=0;
      else if(a==0)
      {
          a=1;
        num++;
      }

   }
    rewind(f);
    printf("         此文件的单词数为:%d\n",num);
          fclose(f);
      }
  • 统计行数函数:当读取字符为换行符'\n'时,行数增加;最后判断末尾字符是否为换行符,若不是则行数加一;
void Line(char *file)
   {
          char c;
          char a;
          int num=0;
          FILE *f;
    if((f=fopen(file,"r"))==NULL)
    {
    printf("         无法打开此文件\n");
             return ;
    }
    while(!feof(f))
    {
        c=fgetc(f);
    if(c=='\n')
    {
        num++;
    }
    a=c;
    }
    if(a!='\n'){
    num++;}
    rewind(f);
    printf("         此文件的行数为:%d\n",num);
     fclose(f);

   }

 

  • 统计统计注释行/空行/代码行行数函数(Anther函数):
  1. 调用strstrc(str1,str2)函数判断每一行是否出现'//',若满足则注释行数增加;
  2. 出现换行符时判断当前行字符数是否为零,若为零则空行数增加;
  3. 调用strlen函数进行判断;
void Anther(char *file){
        int num1=0;
        int num2=0;
        int num3=0;
        char c[100];
        char b;
        char d;
        FILE *f;
        if((f=fopen(file,"r"))==NULL){
                printf("         打开文件出错,请重试!\n");
                return ;
        }
        while(!feof(f)){
                fgets(c,100,f);
                if(strstr(c,"//"))   //判断是否出现‘//
                num1++;}
        rewind(f);
        printf("         此文件的注释行行数为:%d\n",num1);

    while(!feof(f)){
    int flag=0;
    int n=0;

    b=fgetc(f);
    while(!feof(f)){
        if(b=='\n'&&n==0)
        {
            flag=1;
           num2++;
        }

        else if(b!='\n'&&flag==1)
            n++;

        else if(b!='\n'&&flag==0&&n==0)
            {
                n++;
                flag=1;
            }
        else if(b=='\n'&&flag==1&&n>=0){
            n=0;
            flag=0;
        }

        b=fgetc(f);}}
       rewind(f);
        printf("         此文件的空行行数为:%d\n",num2);



         while(!feof(f)){
                fgets(c,100,f);
                if(strstr(c,"//"))
                {
                }
                else  if(strlen(c)>1)     //判断该行长度是否大于1确定是否是空行
               num3++;
            }
            rewind(f);
        printf("         此文件的代码行行数为:%d\n",num3);

    }

 

  • main函数:调用自定义函数
int main(){
    char file[100];
    char choose;
    while(1){
    printf("                      WOED   COUNT           \n");
    printf("         ====================================\n");
    printf("         =                                  =\n");
    printf("         =   一、统计字符数功能 wc.exe-c       =\n");
    printf("         =   二、统计单词数功能 wc.exe-w       =\n");
    printf("         =   三、统计行数功能   wc.exe-l       =\n");
    printf("         =   四、统计空/注释/代码行函数         =\n");
    printf("         =                   wc.exe-a       =\n");
    printf("         =   五、输出全部结果   wc.exe-t       =\n");
    printf("         =                                  =\n");
    printf("         ====================================\n");
    printf("                 请输入功能选项 c/w/l/a/t:");
    scanf(" %c",&choose);
    while(choose!='c'&&choose!='w'&&choose!='l'&&choose!='a'&&choose!='t'){

    printf("                 该功能尚未开发,请重新输入 c/w/l/a/t:");
    scanf(" %c",&choose);
    }
    printf("                 请输入文件地址: ");
        scanf("%s",&file);



    switch(choose){
           case 'c':Character(file);break;
           case 'w':Word(file);break;
           case 'l':Line(file);break;
           case 'a':Anther(file);break;
           case 't':Character(file);Word(file);Line(file);Anther(file);break;
           default :   break;
           }
            }}

六、测试运行

       1. 测试空文件

       2. 测试单字符文件

 

 

       3.测试单字母文件

 

 

       4.测试代码文件

 

 

 

七、项目小结

  1. 这个项目的一些需要用到的知识在之前没有学习过,以致于开始项目前要花费一些时间进行查阅和学习。
  2. 通过记录的PSP表发现实际完成时间比预计完成时间长了一些,在实际操作中编写代码的时间要比预计的时间更短,但是出现的错误比较多导致代码测试过程花费不少时间。总结可知我在编写代码过程中不规范同时对代码的熟悉度也不足。
  3. 在设计Anther函数时有许多不足,导致后面编写代码很麻烦,最后完成的代码也不太美观简洁。

 

posted on 2020-03-24 20:15  mk爱学习  阅读(299)  评论(0编辑  收藏  举报