博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
软件工程第一次作业:个人项目WC
阅读量:6435 次
发布时间:2019-06-23

本文共 5203 字,大约阅读时间需要 17 分钟。

github地址 :

个人项目:WC

1.项目要求

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

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

具体功能要求:

  • 程序处理用户需求的模式为:
    • wc.exe [parameter]
  • 基本功能列表:
    • wc.exe -c file.c //返回文件 file.c 的字符数
    • wc.exe -w file.c //返回文件 file.c 的词的数目
    • wc.exe -l file.c //返回文件 file.c 的行数
  • 扩展功能:
    • -s 递归处理目录下符合条件的文件。
      --a 返回更复杂的数据(代码行 / 空行 / 注释行)。
      • 空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
      • 代码行:本行包括多于一个字符的代码。
      • 注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:
      • } //注释
      • 在这种情况下,这一行属于注释行。
  • 高级功能:
    • -x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。
    • 需求举例:
         - wc.exe -s -a .c
      - 返回当前目录及子目录中所有
      .c 文件的代码行数、空行数、注释行数。

2.遇到的困难及解决方法

主要困难有

  1. 当双引号出现在注释之中时
  2. 当注释符出现在双引号或者是单引号之中时
  3. 当块注释符号出现在行注释符之后时
  4. 当块注释结束之后进入代码行,但是行末再次出现行注释时
  5. 某一行既可以是代码行,也可以是注释行,或者既可以是注释行,也可以是空行

一开始并没有考虑到第五点,然后就写出了一次程序,但是在后来听闻同学找了老师问清楚要求之后,整份代码都进行了重新书写,并且判断注释行,代码行,空行比较麻烦,最终使用了几个bool类型标记终于完成这一功能

当我完成上面所述的问题之后,我觉得我的代码实现能力涨了一大截,并且思考是否还有更为极端得情况。

3.关键代码or设计说明

本文实现了基本功能,和扩展功能

先进行文件内容的读取

bool input(FILE * fp)//读入文本 {     str = "";     char s;     while((s = fgetc(fp)) != EOF)         str = str + s;     str = str + '\n';     if(str.length() == 1)     {         Null = true;     }     return Null; }

基本功能:直接调用相对应的函数完成

void Line()//统计行数{    int num = 0;    for(int i = 0; i < str.length(); i ++)    {        if(str[i] == '\n')   num ++;    }    if(!Null)        printf("行数    :%d\n", num);}void Char()//统计字符{    int num = 0;    for(int i = 0; i < str.length(); i ++)    {        if(str[i] != ' ' && str[i] != '\n' && str[i] != '\t')            num ++;    }    if(!Null)        printf("字符个数 :%d\n", num);}void Words()//统计单词{    int num = 0;    bool flag = 0;    for(int i = 0; i < str.length(); i ++)    {        if(str[i] <= 'z' && str[i] >= 'a' || str[i] <= 'Z' && str[i] >= 'A' || str[i] == '_')        {            if(!flag)   num ++;            flag = true;        }        else flag = false;    }    if(!Null)        printf("单词个数 :%d\n", num);}

调用calc直接对读入的文件进行统计代码行,注释行,空行

void Calc(){bool line_comment = false;  //行注释bool block_comment = false; //块注释标记bool comment_exist = false; //注释出现过标记string s_comment = "";string s_code = "";//注释里面的字符串和代码里面的字符串if(str[0] == '\n')    Empty ++;else  if(str[0] != ' ' && str[0] != '\t')    s_code = s_code + str[0];for(int i = 1; i < str.length(); i ++){    if(str[i] == ' ' || str[i] == '\t')        continue ;    if(str[i] == '\n')    {        if(comment_exist || line_comment || block_comment)            Comment ++;        //注释判断        if(s_comment.length() == 0)        {            if(s_code.length() == 0)                Empty ++;            if(s_code.length() == 1 && (s_code[0] == '{' || s_code[0] == '}' || s_code[0] == ';'))                Empty ++;        }        //空行判断        if(s_code.length() > 1 || (s_code[0] != '{' && s_code[0] != '}' && s_code[0] != ';'))            Code ++;        //代码行判断        s_code = "";        s_comment = "";        line_comment = false;        comment_exist = false;        //换行之后初始化    }    else if(line_comment)    //行注释中    {        s_comment = s_comment + str[i];        comment_exist = true;    }    else if(block_comment)    //块注释中    {        s_comment = s_comment + str[i];        comment_exist = true;        if(str[i - 1] == '*' && str[i] == '/')            block_comment = false;        //块注释终止    }    else if(str[i - 1] == '/' && str[i] == '/')    //将代码字符串最后一个 / 保存到注释字符串之中,并行注释标记为真    {        s_code = s_code.substr(0, s_code.length() - 1);        s_comment = s_comment + str[i - 1] + str[i];        line_comment = true;        comment_exist = true;    }    else if(str[i - 1] == '/' && str[i] == '*')    //将代码字符串最后一个 / 保存到注释字符串之中,并块注释标记为真    {        s_code = s_code.substr(0, s_code.length() - 1);        s_comment = s_comment + str[i - 1] + str[i];        block_comment = true;        comment_exist = true;    }    else if(str[i] == '\"')    //读到双引号时,直接循环到下一个双引号, 并保存至代码字符串之中    {        s_code = s_code + str[i];        while(str[++ i] != '\"')        {            s_code = s_code + str[i];        }        s_code = s_code + str[i];    }    else if(str[i] == '\'')    //读到单引号时,直接循环到下一个单引号, 并保存至代码字符串之中    {        s_code = s_code + str[i];        while(str[++ i] != '\'')        {            s_code = s_code + str[i];        }        s_code = s_code + str[i];    }    else    //普通字符        s_code = s_code + str[i];}if(!Null){    printf("注释行数 : %d\n", Comment);    printf("代码行数 : %d\n", Code);    printf("空行数   : %d\n", Empty);}

4.测试报告

由于技术有限,笔者采取的是手工测试

第一组测试结果如下:

如图
这里写图片描述

第二组测试结果如下:

这里写图片描述

第三组测试结果如下:

这里写图片描述

第四组测试结果如下:

这里写图片描述

这里写图片描述

5.PSP

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 15 40
· Estimate · 估计这个任务需要多少时间 15 40
Development 开发 540 915
· Analysis · 需求分析 (包括学习新技术) 180 300
· Design Spec · 生成设计文档 30 30
· Design Review · 设计复审 (和同事审核设计文档) 15 15
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 0 0
· Design · 具体设计 15 60
· Coding · 具体编码 150 180
· Code Review · 代码复审 30 90
· Test · 测试(自我测试,修改代码,提交修改) 120 240
Reporting 报告 160 230
· Test Report · 测试报告 120 180
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 40
合计 715 1185

5. 记录自己的学习进度条(每周追加)

第N周 新增代码行 累计代码 本周学习耗时 累计学习耗时
1 100 100 8 8
2 215 215 11.5 19.5

转载于:https://www.cnblogs.com/zhangab/p/9629782.html

你可能感兴趣的文章
runtime自我总结
查看>>
Collapsible Widget Area
查看>>
阿里云 api 网关签名 sdk-node
查看>>
shell编程基础入门笔记
查看>>
Android中SQLite应用详解
查看>>
CoolHash数据库的产品宣言(Fourinone4.0版)
查看>>
TI-BASIC 计算器游戏开发之文字、图形、音频教程:前言
查看>>
SpringMVC 学习系列 (2) 之 经典的HelloWorld 实现
查看>>
Java并发编程基础-线程-创建
查看>>
Caused by: java.sql.SQLException: ORA-00911: inval
查看>>
JavaScript 模块应用与编程
查看>>
Tomcat源码解读系列(三)——Tomcat对HTTP请求处理的整体流程
查看>>
ZTREE学习二
查看>>
网络访问的往返时间
查看>>
用Docker部署MariaDB
查看>>
java并发编程(四): 基础构建模块
查看>>
require异步加载vue组件可能导致的问题
查看>>
数据类型
查看>>
【Xcode】类名点击command找不到实现
查看>>
SwiftCommon之Cookie处理
查看>>