软件工程第一次个人编程作业

小茄77 2021-09-20 21:49:37

 

 

这个作业属于哪个课程构建之法-2021秋-福州大学软件工程
这个作业要求在哪里2021秋软工实践第一次个人编程作业
这个作业的目标实现一个程序功能,它可以对读入的C或C++代码文件进行不同等级的关键字提取。
学号031902334

GitHub仓库地址:CC仓库

PSP表格

PSP预估耗时(分钟)实际耗时(分钟)
计划1520
估计任务需要多长时间785950
开发----
需求分析(包括学习新技术)6070
生成设计文档3030
设计复审1010
代码规范2030
具体设计6080
具体编码300360
代码复审100100
测试80100
报告6050
测试报告2030
计算工作量1515
事后总结1525
合计785

950

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

解题思路

  • 先进行文件的读取和分析
  • 将字符进行分割和保存
  • 与关键字进行比对
  • 统计switch及对应case数量

因为考虑到自己现有的能力,所以只进行到switch查找的任务,并不考虑有switch嵌套的复杂情况。

流程图如下:

代码说明

文件读取

在网上搜索了如何读取文件,并最终选用如下的方法逐行读取,运用getline()

有个小插曲是我不知道怎么在Mac上找到文件的地址,搜了半天才弄清楚是要拷贝文件然后在终端粘贴就可以得到地址。

std::fstream in("/Users/dongxiaoou/Documents/test.txt",std::fstream::in);
    //表示以只读方式打开文件

提取英文字符 识别到分隔符后进行保存 删除注释

因为关键字都是字母,所以我选择提取文件中所有的英文字母字符,并将' '、'<'、'>'、'='、'{'、'}'、'/n'、'.'视为分割符号,当字符串后有这些时,认为前面部分是一个整体,并保存在arr字符串数组中。同时识别连续两个'/'字符,认为改行其后语句为注释语句,将其删除。

while (getline(in, text))
    {
      for(int k=0;k<text.length();k++){
        int flag=0;
          sc=text[k];
        if(('a'<=sc&&sc<='z')||('A'<=sc&&sc<='Z'))//将字母存入字符数组中
              tra[i++]=sc;
        if(sc==' '||sc=='>'||sc=='<'||sc=='='||sc=='{'||sc=='('||sc=='\n'||sc=='.')
            //字母后有符号则存入字符串数组等待判断
        {
            arr[j]=tra;//存入字符串数组中
           memset(tra,'\0',sizeof(tra));//将字符数组清零
            i=0;
            j++;
        }
         if(sc=='/')//删除注释语句
         {
             if(flag==0)
                 flag=1;
             if(flag==1)
                 break;
         }
       }
     }

进行关键字的比对和记录 

将arr字符串依次与关键字字符串进行比较,运动了compare函数,如果相同,则将tol数量+1。

for(int x=0;x<j;x++)  //关键字判断
    {
        for(int y=0;y<=31;y++)
        {
            //看是否有关键字
            if(keyword[y].compare(arr[x])==0)
                tol++;
        }
    }

统计switch和case的数量

对switch进行识别,同样运用了compare函数,如果识别到switch,*则接下来开始识别case,如识别到case,对存放case数量的数组元素进行加1操作。如果接下来识别到了switch,则认为到达了下一组switch结构,对存放case数量数组ncase的下标进行加1操作,重复*后的操作。

//不考虑switch嵌套的复杂情况 统计switch和case的数量
    int nswitch=0,ncase[200];
    int nc=0;
    for(int x=0;x<j;x++)
    {
        if(arr[x].compare(keyword[0])==0){
            nswitch++;
            nc++;
        }
        if(arr[x].compare(keyword[3])==0){
            ncase[nc]++;
        }
    }

完整代码

#include<iostream>
#include<string>
#include<fstream>
using namespace std;
int main()
{
    int tol=0;
    int i=0,j=0;
    char sc;
    std::fstream in("/Users/dongxiaoou/Documents/test.txt",std::fstream::in);
    //表示以只读方式打开文件
    string arr[100005];  //建立字符串数组
    string text;         //读取到的一行字符串
    char tra[250];      //作为临时存储的字符数组
    while (getline(in, text))
    {
      for(int k=0;k<text.length();k++){
        int flag=0;
          sc=text[k];
        if(('a'<=sc&&sc<='z')||('A'<=sc&&sc<='Z'))//将字母存入字符数组中
              tra[i++]=sc;
        if(sc==' '||sc=='>'||sc=='<'||sc=='='||sc=='{'||sc=='('||sc=='\n'||sc=='.')
            //字母后有符号则存入字符串数组等待判断
        {
            arr[j]=tra;//存入字符串数组中
           memset(tra,'\0',sizeof(tra));//将字符数组清零
            i=0;
            j++;
        }
         if(sc=='/')//删除注释语句
         {
             if(flag==0)
                 flag=1;
             if(flag==1)
                 break;
         }
       }
     }
    string keyword[] = {"switch","auto","break","case","char","const","continue","default","do","double","else","enum","extern","float","for","goto","if","int","long","register","return","short","signed","sizeof","static","struct","typedef","union","unsigned","void","volatile","while"};
    //将关键字输入keyword字符串数组
    for(int x=0;x<j;x++)  //关键字判断
    {
        for(int y=0;y<=31;y++)
        {
            //看是否有关键字
            if(keyword[y].compare(arr[x])==0)
                tol++;
        }
    }
    //不考虑switch嵌套的复杂情况 统计switch和case的数量
    int nswitch=0,ncase[200];
    int nc=0;
    for(int x=0;x<j;x++)
    {
        if(arr[x].compare(keyword[0])==0){
            nswitch++;
            nc++;
        }
        if(arr[x].compare(keyword[3])==0){
            ncase[nc]++;
        }
    }
    cout<<"total num: ";
    cout<<tol<<endl;
    cout<<"switch num: ";
    cout<<nswitch<<endl;
    cout<<"case num: ";
    for(int i=1;i<=nc;i++)
        cout<<' '<<ncase[i];
    cout<<endl;
    in.close();
    return 0;
}

单元测试

结果与预期一致 但仅对简单样例进行测试 复杂代码可能会出现错误 当前能力还不足以解决更复杂情况 会通过之后的学习努力提高

性能测试

自己电脑没有搞清楚怎么做,所以把自己的代码发给同学帮忙进行了测试。。

作业总结

  •     在一开始的github使用中就遇到了一些问题,因为是之前从未接触过的东西,还是全英文,所以感到使用起来有一些吃力,在自己查阅资料和寻求同学帮助之后创建了仓库并学会了上传文件,也初步熟悉了GitHub的界面。
  •    由于编程能力的欠缺,所以很多想法在脑子里却不能通过代码表达出来,所以还要通过之后的不断学习、练习来弥补。
  •    基本了解了c++中文件读取的方法,算是掌握了一个小小的新技能。
  •    之前就对字符串的掌握不够熟练,通过这次作业复习了一些之前学习过的对字符串处理的函数,也学习到了对字符串整体进行清空操作的memset函数。
  •    本次作业实现使用的都是最基本的循环结构和字符串的运用,没能用到栈的知识,因为自己对其掌握非常欠缺,导致代码处理复杂问题可能会出现错误。会吸取这次的经验教训,在之后的时间里花费更多时间去学习知识和完善自己。

 

 

...全文
423 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

189

社区成员

发帖
与我相关
我的任务
社区描述
福州大学软件工程教学,推行邹欣老师“构建之法”。
软件工程 高校
社区管理员
  • Dawnfox
  • REP1USONE
  • 纪华裕
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧