【苏大C++期中模拟题】

目录

1.题目

2. 解题代码

3. 问题总结


1.题目

考试说明

  1. 考试时间:合计2小时。允许提前交卷。
  2. 考试过程中,不能连接未经指定网站或服务器。
  3. 闭卷考试部分,不能查阅任何类型的参考资料。
  4. 开卷考试部分,可以查阅纸质文档,不能查阅任何类型的电子文档。
  5. 考试过程中,不得使用任何形式的电子存储设备,不可使用手机。
  6. 违反上述2-5条者,视为考试作弊。

编程题提交方式(100分,开卷)

  1. 提交前务必关闭vs2005vs2008或vs2010编程环境。
  2. 所有源程序内容必须仅包含在一个源程序文件(CPP文件)中。
  3. 在浏览器的地址栏中输入http://192.168.125.3,点击相应链接进入提交页面。
  4. 按要求输入两遍自己的学号。
  5. 点击“选择文件”按钮,选择自己的源程序文件。点击“提交”按钮提交。
  6. 如提交成功,系统会显示相关信息。如果提交不成功,请重复步骤16-18。
  7. 提交成功后,可点击“查看内容”按钮检查提交的内容。


按以下要求编写程序

题目说明

请各位考生课程信息发布网站下载数据文件input.txt,然后将该数据文件手动保存D盘根目录下。该文件中的数据以文本形式存储,其中包含了若干个同学的期中考试成绩记录,每个人最多有三门课,分别为Math、English和C++,每门课的成绩占一行,每行包括学号、课程名称和成绩,三者之间用‘\t’分开。

请按要求依次完成如下操作:

  1. 编写一个函数ReadFile。读取input.txt文件中的所有记录,并将它们存放在struct mark结构体类型的marks向量中。
  2. 编写一个函数ShowData。显示第1步中生成的marks向量的前5条。要求学号占15列左对齐,课程名称占10列左对齐,成绩占8列右对齐,本函数如果调用时不指定显示条数,则显示marks向量的前3条(当数据不足3条时,则全部显示)。
  3. 编写一个函数Filter,将marks向量中所有不合法的数据删除,所谓不合法的数据就是考试成绩小于0或者大于100,然后在屏幕上显示删除的条数。
  4. 编写一个函数FillData,将marks向量中所有数据按学号和课程名称汇总到struct student类型的向量stus中,汇总规则是:1)在stus中每个学号的学生只有一个元素;2)在stus中每个元素有三个成绩;3)汇总时如果某个学号在marks中不足三个成绩,对应stus中元素的对应成绩数据填0。
  5. 编写一个函数SortData,对向量stus按照三门课的总分从高到低排序,当总分相同时,按照学号从小到大排序。
  6. 编写一个函数ShowData,将stus向量中的最后5行数据显示在屏幕上(如果不足5行,则显示全部),要求学号占15列左对齐,Math成绩占5列右对齐,English占5列右对齐,C++占5列右对齐。
  7. 编写一个函数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或者大于100
	vector<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); //读取文件的数据到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("/Users/apple/Downloads/1-1/res.txt",stus);

		return 0;
}

3. 问题总结

(1) 如何在不用全局变量的条件下在函数中修改主函数中的内容?

答:引用。引用相当于给主函数中传进来的变量起了个别名,两者还是相关联的。这个别名不能给主函数中的别的变量使用。

(2)记得读完文件进行close()操作,养成良好习惯从我做起~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值