【苏大C++期中模拟题】
目录
1.题目
2. 解题代码
3. 问题总结
1.题目
考试说明
- 考试时间:合计2小时。允许提前交卷。
- 考试过程中,不能连接未经指定网站或服务器。
- 闭卷考试部分,不能查阅任何类型的参考资料。
- 开卷考试部分,可以查阅纸质文档,不能查阅任何类型的电子文档。
- 考试过程中,不得使用任何形式的电子存储设备,不可使用手机。
- 违反上述2-5条者,视为考试作弊。
编程题提交方式(100分,开卷)
- 提交前务必关闭vs2005、vs2008或vs2010编程环境。
- 所有源程序内容必须仅包含在一个源程序文件(CPP文件)中。
- 在浏览器的地址栏中输入http://192.168.125.3,点击相应链接进入提交页面。
- 按要求输入两遍自己的学号。
- 点击“选择文件”按钮,选择自己的源程序文件。点击“提交”按钮提交。
- 如提交成功,系统会显示相关信息。如果提交不成功,请重复步骤16-18。
- 提交成功后,可点击“查看内容”按钮检查提交的内容。
按以下要求编写程序
题目说明
请各位考生从课程信息发布网站下载数据文件input.txt,然后将该数据文件手动保存在D盘根目录下。该文件中的数据以文本形式存储,其中包含了若干个同学的期中考试成绩记录,每个人最多有三门课,分别为Math、English和C++,每门课的成绩占一行,每行包括学号、课程名称和成绩,三者之间用‘\\t’分开。
请按要求依次完成如下操作:
- 编写一个函数ReadFile。读取input.txt文件中的所有记录,并将它们存放在struct mark结构体类型的marks向量中。
- 编写一个函数ShowData。显示第1步中生成的marks向量的前5条。要求学号占15列左对齐,课程名称占10列左对齐,成绩占8列右对齐,本函数如果调用时不指定显示条数,则显示marks向量的前3条(当数据不足3条时,则全部显示)。
- 编写一个函数Filter,将marks向量中所有不合法的数据删除,所谓不合法的数据就是考试成绩小于0或者大于100,然后在屏幕上显示删除的条数。
- 编写一个函数FillData,将marks向量中所有数据按学号和课程名称汇总到struct student类型的向量stus中,汇总规则是:1)在stus中每个学号的学生只有一个元素;2)在stus中每个元素有三个成绩;3)汇总时如果某个学号在marks中不足三个成绩,对应stus中元素的对应成绩数据填0。
- 编写一个函数SortData,对向量stus按照三门课的总分从高到低排序,当总分相同时,按照学号从小到大排序。
- 编写一个函数ShowData,将stus向量中的最后5行数据显示在屏幕上(如果不足5行,则显示全部),要求学号占15列左对齐,Math成绩占5列右对齐,English占5列右对齐,C++占5列右对齐。
- 编写一个函数WriteFile。将经过第5步处理的向量stus中所有数据写入到指定文本文件result.txt中,要求学号占15列左对齐,Math成绩占5列右对齐,English占5列右对齐,C++占5列右对齐。
涉及结构体定义如下:
struct mark
{
string xh;//学号
string kc;//课程名称
int cj;//成绩
};
struct student
{
string xh; //学号
int math; //数学成绩
int english; //英语成绩
int cplusplus; //C++成绩
};
main函数如下:
int main()
{
vector <struct mark> marks;
ReadFile("d:\\\\input.txt", marks); //读取文件的数据到marks
cout << "数据总条数为:" << marks.size() << endl; //显示数据总数
ShowData(marks,5);
int count=Filter(marks);//删除其中不合法的数据
cout << "合计删除了" << count << "条不合法成绩" << endl;
vector<struct student> stus=FillData(marks);
cout <<"汇总结果合计有"<< stus.size()<<"人"<< endl;
SortData (stus);
cout << "总分最低的5人信息为" << endl;
ShowData(stus,5);
WriteFile("d:\\\\res.txt",stus);
return 0;
}
注意: 不允许修改main函数,每修改一处,扣3分;
评分标准
(编程题满分为80分)
大项 |
子项 |
评分项 |
应得分 |
实得分 |
正 确 性
70分 |
结果(70分) 含编译子项5分 |
读成绩的ReadFile函数 |
10 |
|
ShowData函数(struct mark向量版本) |
8 |
|
||
Filter函数 |
12 |
|
||
FillData函数 |
12 |
|
||
SortData函数 |
10 |
|
||
ShowData函数(struct student向量版本) |
8 |
|
||
WriteFile函数 |
10 |
|
||
上述各项都不得分 |
见编译子项 |
本项不得分 |
||
程序运行出现异常 |
-10 |
|
||
程序死循环 |
-10 |
|
||
修改main函数 |
-3(每处修改) |
|
||
编译(5分) |
编译连接均通过(无warning) |
5 |
|
|
编译连接均通过(有warning) |
3 |
|
||
编译通过、连接不通过 |
2 |
|
||
编译、连接均不通过 |
0 |
|
||
可 读 性 10分 |
缩进对齐(4分) |
正确运用缩进对齐规则 |
4 |
|
有缩进对齐但不完全符合要求 |
3 |
|
||
没有使用缩进对齐规则 |
2 |
|
||
注释(3分) |
有详细且正确的注释 |
3 |
|
|
有注释,但不够详细 |
2 |
|
||
完全没有注释 |
0 |
|
||
变量命名(3分) |
变量命名有规则 |
3 |
|
|
变量命名有规则、但规则使用不一致 |
2 |
|
||
变量命名无规则 |
0 |
|
2. 解题代码
#include <iostream>
#include <vector>
#include<fstream>
#include<iomanip>
#include<algorithm>
using namespace std;struct mark{string xh;//学号string kc;//课程名称int cj;//成绩
};struct student
{string xh; //学号int math; //数学成绩int english; //英语成绩int cplusplus; //C++成绩
};void ReadFile(string path, vector<struct mark>&Marks){ifstream ifile(path);while(!ifile.eof()){mark m;if(ifile>>m.xh>>m.kc>>m.cj){Marks.push_back(m);}}ifile.close();
}void ShowData(const vector<struct mark>&Marks, int n=3){//要求学号占15列左对齐,课程名称占10列左对齐,成绩占8列右对齐for(int i=0;i<Marks.size();i++){cout<<left<<setw(15)<<Marks[i].xh;cout<<left<<setw(10)<<Marks[i].kc;cout<<right<<setw(8)<<Marks[i].cj;cout<<endl;if(i+1==n){break;}}
}int Filter(vector<struct mark>&Marks){//所谓不合法的数据就是考试成绩小于0或者大于100vector<struct mark>::iterator it;int tempc;tempc=0;for(it=Marks.begin();it!=Marks.end();){if(it->cj<0 or it->cj>100){it=Marks.erase(it);tempc++;}else{it++;}}return tempc;
}vector<struct student>FillData( const vector<struct mark>&Marks){vector<struct student>newv;for(int i=0;i<Marks.size();i++){int j;for(j=0;j<newv.size();j++){if(newv[j].xh==Marks[i].xh){break;}}if(j==newv.size()){student v;v.xh=Marks[i].xh;v.math=v.english=v.cplusplus=0;if(Marks[i].kc=="Math"){v.math=Marks[i].cj;}else if (Marks[i].kc=="English"){v.english=Marks[i].cj;}else{v.cplusplus=Marks[i].cj;}newv.push_back(v);}else{if(Marks[i].kc=="Math"){newv[j].math=Marks[i].cj;}else if (Marks[i].kc=="English"){newv[j].english=Marks[i].cj;}else{newv[j].cplusplus=Marks[i].cj;}}}return newv;
}bool cmp(student a, student b){//对向量stus按照三门课的总分从高到低排序//按照学号从小到大排序if((a.cplusplus+a.english+a.math)==(b.cplusplus+b.english+b.math)){return a.xh<b.xh;}else{return (b.cplusplus+b.english+b.math)<(a.cplusplus+a.english+a.math);}
}
void SortData(vector<struct student>&Stus){sort(Stus.begin(),Stus.end(),cmp);
}void ShowData(const vector<struct student>&Stus,int n=5){//将stus向量中的最后5行数据显示在屏幕上(如果不足5行,则显示全部)for(int i=0;i<n;i++){int l=Stus.size()-1-i;//要求学号占15列左对齐,Math成绩占5列右对齐,English占5列右对齐,C++占5列右对齐。cout<<left<<setw(15)<<Stus[l].xh;cout<<right<<setw(5)<<Stus[l].math;cout<<right<<setw(5)<<Stus[l].english;cout<<right<<setw(5)<<Stus[l].cplusplus<<endl;if(l==0){break;}}
}void WriteFile(string path,const vector<struct student>&Stus){ofstream ofile(path);for(int i=0;i<Stus.size();i++){ofile<<left<<setw(15)<<Stus[i].xh;ofile<<right<<setw(5)<<Stus[i].math;ofile<<right<<setw(5)<<Stus[i].english;ofile<<right<<setw(5)<<Stus[i].cplusplus<<endl;}ofile.close();
}int main()
{vector <struct mark> marks;ReadFile("/Users/apple/Downloads/1-1/input.txt", marks); //读取文件的数据到markscout << "数据总条数为:" << marks.size() << endl; //显示数据总数ShowData(marks,5);int count=Filter(marks);//删除其中不合法的数据cout << "合计删除了" << count << "条不合法成绩" << endl;vector<struct student> stus=FillData(marks);cout <<"汇总结果合计有"<< stus.size()<<"人"<< endl;SortData (stus);cout << "总分最低的5人信息为" << endl;ShowData(stus,5);WriteFile("/Users/apple/Downloads/1-1/res.txt",stus);return 0;
}
3. 问题总结
(1) 如何在不用全局变量的条件下在函数中修改主函数中的内容?
答:引用。引用相当于给主函数中传进来的变量起了个别名,两者还是相关联的。这个别名不能给主函数中的别的变量使用。
(2)记得读完文件进行close()操作,养成良好习惯从我做起~