• 个人项目作业(wc.exe)


    1.GitHub项目地址

    https://github.com/QiuBin666/WC

    项目介绍:

    题目描述

    Word Count
    1. 实现一个简单而完整的软件工具(源程序特征统计程序)。
    2. 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
    3. 进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。

    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   返回更复杂的数据(代码行 / 空行 / 注释行)。

    空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。

    代码行:本行包括多于一个字符的代码。

    注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:

        } //注释
    在这种情况下,这一行属于注释行。

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

    高级功能:

     -x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。

    需求举例:
      wc.exe -s -a *.c


    返回当前目录及子目录中所有*.c 文件的代码行数、空行数、注释行数。

    2.PSP预计时间

    PSP2.1

    Personal Software Process Stages

    预估耗时(分钟)

    实际耗时(分钟)

    Planning

    计划

     30

     

    · Estimate

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

     30

     

    Development

    开发

     180

     

    · Analysis

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

     200

     

    · Design Spec

    · 生成设计文档

     30

     

    · Design Review

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

     0

     

    · Coding Standard

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

    20

     

    · Design

    · 具体设计

    30

     

    · Coding

    · 具体编码

     360

     

    · Code Review

    · 代码复审

     20

     

    · Test

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

    120

     

    Reporting

    报告

     120

     

    · Test Report

    · 测试报告

     60

     

    · Size Measurement

    · 计算工作量

     30

     

    · Postmortem & Process Improvement Plan

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

     60

     

    合计

     

     1290

     

    3.解题思路

    拿到题目后首先想到的是:要对文件进行读写操作,但这是以前的编程经历中从未涉及到的,所以首先去学习了c语言文件读写相关的知识。

    学习相关知识后,就到了该如何实现功能的问题了,解决方法是划分为几个功能模块,每个模块实现一个功能。

    4.设计实现过程

    设计字符数统计函数void CharCount():当判定为字符便计数,非字符则不计。

    设计单词数统计函数void WordCount():通过从第一个字母开始读取连续的字母。

    设计行数统计函数 void LineCount():判断行数可以判断是否出现‘ ’或‘ ’来判断。
    设计扩展功能统计函数int Extend():

        1、空行计算,如果一行中没有字符或者最多有一个'{'或者'}'(可能遇到‘ ’或者‘ ’)算为空行。

        2、注释行计算,通过读取第一个字符为/进入判断,读取第二个字符为*或者/实现。

        3、代码行计算,排除空行和注释行之外的即为代码行。

    5.代码说明 

    主函数:

     1 int a=0;
     2 int b=0;
     3 int c=0;
     4 int main() { //主函数
     5     void CharCount(char filename[]);//字符数统计函数 
     6     void WordCount(char filename[]);//单词数统计函数
     7     void LineCount(char filename[]);//行数统计函数  
     8     int Extend(char filename[]);//扩展功能统计函数 
     9     char input[10], filename[32];
    10     while (1) {
    11         //输入指令
    12         printf("wc.exe - c file.c      返回文件的字符数
    wc.exe - w file.c      返回文件的词的数目
    wc.exe - l file.c      返回文件的行数
    wc.exe - a file.c      返回更复杂的数据(代码行 / 空行 / 注释行)
    wc.exe - o file.c      退出
    请输入指令:- ");
    13         scanf("%s",&input);
    14         
    15         switch(input[0]){
    16             case 'c':  //字符数
    17                 printf("请输入文件名:");//输入文件名
    18                 scanf("%s", &filename);
    19                 CharCount(filename);
    20                 printf("文件的字符数为:%d",a);
    21                 break;
    22         
    23             case 'w':  //词数                
    24                 printf("请输入文件名:");//输入文件名
    25                 scanf("%s", &filename);
    26                 WordCount(filename);
    27                 printf("文件的词数为:%d", b);
    28                 break;
    29 
    30             case 'l':  //行数
    31                 printf("请输入文件名:");//输入文件名
    32                 scanf("%s", &filename);           
    33                 LineCount(filename);
    34                 printf("文件的行数为:%d", c);
    35                 break;
    36 
    37             case 'a':    //返回更复杂的数据(代码行 / 空行 / 注释行)。
    38                 printf("请输入文件名:");//输入文件名
    39                 scanf("%s", &filename);
    40                 Extend(filename);
    41                 break;
    42         
    43             case 'o':  //退出
    44                 return 0;
    45 
    46             default:
    47                 printf("你输入的指令有误!请重新输入");
    48                 break;
    49         }
    50 
    51     }
    52     system("pause");
    53     return 0;
    54 }

    各子模块功能函数:

    计算字符数:

     1 void CharCount(char filename[]){//字符数统计函数 
     2     FILE *fp=NULL;
     3     fp=fopen(filename,"r");
     4     if(fp==NULL){
     5         printf("寻找文件失败
    ");
     6         exit(-1);
     7     }
     8     char ch;
     9     ch = fgetc(fp);
    10     while(ch!=EOF){
    11         if (ch != ' '&&ch != '
    '&&ch != '	'&&ch != ','&&ch != '.'&&ch != '!'&&ch != ';'&&ch != '=');
    12         a++; 
    13         ch = fgetc(fp);  
    14     }
    15     a--;
    16     fclose(fp);
    17 }

    计算词数:

     1 void WordCount(char filename[]){//单词数统计函数 
     2     FILE *fp = NULL;
     3     fp=fopen(filename,"r");
     4     if(fp==NULL){
     5         printf("寻找文件失败
    ");
     6         exit(-1);
     7     }
     8     char fchar = 0;
     9     fchar = fgetc(fp);
    10     while (fchar != EOF)
    11     {
    12         if ((fchar >= 'a' && fchar <= 'z') || (fchar >= 'A' && fchar <= 'Z') )//遇到字母
    13         {
    14             while ((fchar >= 'a' && fchar <= 'z') || (fchar >= 'A' && fchar <= 'Z'))
    15                 fchar = fgetc(fp);
    16                 b++;
    17                 fchar = fgetc(fp);
    18         }
    19         else {
    20             fchar = fgetc(fp);
    21         }
    22     }
    23     fclose(fp);
    24   
    25 }

    计算行数:

     1 void LineCount(char filename[]){//行数统计函数 
     2     FILE *fp = NULL;
     3     fp=fopen(filename,"r");
     4     if(fp==NULL){
     5         printf("寻找文件失败
    ");
     6         exit(-1);
     7     }
     8     char ch;
     9     ch = fgetc(fp);
    10     while (ch != EOF)
    11     {
    12         if (ch == '
    ' || ch == '	')
    13             c++;
    14         ch = fgetc(fp);
    15     }
    16     fclose(fp);
    17 }

    扩展功能函数:

     1 int Extend(char filename[]) {  //扩展功能 
     2     FILE *fp = NULL;
     3     fp = fopen(filename, "r");
     4     if (fp == NULL) {
     5         printf("寻找文件失败
    ");
     6         exit(-1);
     7     }
     8 
     9     char fchar = 0;
    10     int emptyline = 0, code = 0, note = 0;
    11     int l = 0, n = 0, c = 0;//l为空行类型,0是无字符空行,1是1字符空行;n为注释类型,0为非注释行,1为单注释行,2为多注释行,c为代码类型
    12 
    13     while (fchar != EOF) {
    14         fchar = fgetc(fp);
    15             if (l == 0 || l == 1) {//如果开始是空格或制表,开始判断是不是空行或者注释行或者代码行
    16                 if (fchar == '
    ') {//回车之前没有字符,空行;1字符进入后也是没有其他字符
    17                     emptyline++;
    18                     l = 0;
    19                     continue;
    20                 }
    21                 else if (fchar == '/') {//注释判断
    22                     fchar = fgetc(fp);
    23                     if (fchar == '/') {//单行注释
    24                         n = 1;
    25                         while (fchar != EOF && fchar != '
    ') {
    26                             fchar = fgetc(fp);
    27                         }
    28                         n = 0;
    29                         note++;
    30                         continue;
    31                     }
    32                     else if (fchar == '*') {//多行注释
    33                         n = 2;
    34                         continue;
    35                     }
    36                 }
    37                 else if( fchar == '}' && l == 0){
    38                     l = 1;        //一字符空行
    39                     continue;
    40                 }
    41                 else if(fchar == ' ' || fchar == '	'){
    42                     continue;
    43                 }
    44                 else {
    45                     c = 1;
    46                 }
    47             }
    48             if (c == 1) {//代码行
    49                 while (fchar != EOF && fchar != '
    ') {
    50                     fchar = fgetc(fp);
    51                 }
    52                 l = 0;//状态变回空行
    53                 code++;
    54                 continue;
    55             }
    56             if (n == 2) {//多行注释
    57                 while (fchar != EOF && fchar != '*') {
    58                     while (fchar != EOF && fchar != '
    ') {
    59                         fchar = fgetc(fp);
    60                     }
    61                     note++;
    62                     fchar = fgetc(fp);
    63                 }
    64                 fchar = fgetc(fp);
    65                 if (fchar == '/') {//多行结束
    66                     n = 0;
    67                 }
    68                 continue;
    69             }
    70     }
    71     printf("
    共有空行数: %d  
    代码行数: %d  
    注释行数: %d
    ", emptyline, code, note);
    72     fclose(fp);
    73 }

    6.测试运行

    基本功能测试用例

    测试-c功能:

     

     测试-w功能:

     测试-l功能:

    扩展功能测试用例

     测试-a功能:

    7.实际花费的时间

    PSP2.1

    Personal Software Process Stages

    预估耗时(分钟)

    实际耗时(分钟)

    Planning

    计划

     30

     35

    · Estimate

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

     30

    20

    Development

    开发

     180

     240

    · Analysis

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

     200

    180 

    · Design Spec

    · 生成设计文档

     30

    20

    · Design Review

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

     0

    · Coding Standard

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

    20

    10 

    · Design

    · 具体设计

    30

    60 

    · Coding

    · 具体编码

     360

    540

    · Code Review

    · 代码复审

     20

    60

    · Test

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

    120

    180

    Reporting

    报告

     120

     100

    · Test Report

    · 测试报告

     60

     30

    · Size Measurement

    · 计算工作量

     30

     20

    · Postmortem & Process Improvement Plan

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

     60

     40

    合计

     

    1290

     1535

    8.项目小结

    收获:作为第一次项目经历,对软件工程的设计流程有了新的认识,一个项目的实现,重要的往往不是代码的质量,而是一个好的框架和一个良好的开发习惯,在这次开发过程中深刻的认识到这两点的重要性。

    不足:基础知识的不足,导致前期准备时间过长。解决问题能力不足,导致编码所需时间长、错误多,部分功能完全没能力实现,需多学、多练。开发经验少,整个开发过程并不流畅。

  • 相关阅读:
    MySql不允许对同一张表同时进行查询和更新
    MysSql 显示不了中文、乱码问题
    SpringBoot参数访问
    那些年我看过的好文
    关于远程调试
    算法题
    Spring Boot 注解学习
    linux 设置ssh免密登录
    ORA各种错误
    listener.ora tnsnames.ora
  • 原文地址:https://www.cnblogs.com/Qiu-Bin/p/12501080.html
Copyright © 2020-2023  润新知