189
社区成员




这个作业属于哪个课程 | 构建之法-2021秋-福州大学软件工程 |
这个作业要求在哪里 | 2021秋软工实践第一次个人编程作业 |
这个作业的目标 | 实现一个程序功能,它可以对读入的C或C++代码文件进行不同等级的关键字提取。 |
学号 | 031902334 |
PSP | 预估耗时(分钟) | 实际耗时(分钟) |
计划 | 15 | 20 |
估计任务需要多长时间 | 785 | 950 |
开发 | -- | -- |
需求分析(包括学习新技术) | 60 | 70 |
生成设计文档 | 30 | 30 |
设计复审 | 10 | 10 |
代码规范 | 20 | 30 |
具体设计 | 60 | 80 |
具体编码 | 300 | 360 |
代码复审 | 100 | 100 |
测试 | 80 | 100 |
报告 | 60 | 50 |
测试报告 | 20 | 30 |
计算工作量 | 15 | 15 |
事后总结 | 15 | 25 |
合计 | 785 |
950 |
因为考虑到自己现有的能力,所以只进行到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;
}
结果与预期一致 但仅对简单样例进行测试 复杂代码可能会出现错误 当前能力还不足以解决更复杂情况 会通过之后的学习努力提高
自己电脑没有搞清楚怎么做,所以把自己的代码发给同学帮忙进行了测试。。