当前位置:   article > 正文

从0到1入门C++编程——12 演讲比赛流程管理系统

从0到1入门C++编程——12 演讲比赛流程管理系统


演讲比赛流程管理系统
比赛规则:演讲比赛共有12个人参加,比赛分两轮进行,第一轮为淘汰赛,第二轮为决赛。每名选手都有对应的编号,如10001~10012,可以根据届数的不同修改选手编号,第一轮分为两个小组,每组6个人,整体按照选手编号进行抽签后顺序演讲。十个评委分别给每名选手打分,去除最高分和最低分,平均分作为本轮选手的成绩。第一轮过后,分别淘汰两组内排名后三名的选手,每组前三名晋级。第二轮为决赛,前三名胜出,每轮比赛过后需要显示晋级选手的信息。
程序功能
开始演讲比赛:完成整届比赛的流程,每个比赛阶段需要给用户一个提示,用户按任意键后继续下一个阶段;
查看往届记录:查看之前比赛前三名结果,每次比赛都会记录到文件中,文件用.csv后缀名保存;
清空比赛记录:将文件中数据清空;
退出比赛程序:用户输入某一选择后退出程序。


一、创建类并显示菜单

创建管理类头文件和cpp文件,在头文件中创建一个类,后续相关的成员函数在类中进行声明,具体的实现在cpp文件中。
在这里插入图片描述
菜单显示功能的实现步骤:先在头文件speechManager.h中声明显示菜单的函数,然后在speechManager.cpp中实现该函数,再到main.cpp中通过实例化对象调用该函数接口。之后的功能基本上都是按照这个步骤进行的。
头文件speechManager.h中声明显示菜单函数的代码如下。

#pragma once
#include <iostream>
using namespace std;

class speechManager
{
public:
	speechManager();  //构造函数
	void show_menu();  //显示菜单
	~speechManager();  //析构函数
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在speechManager.cpp中实现显示菜单的代码如下。

void speechManager::show_menu()  //显示菜单
{
	cout<<"****************************************"<<endl;
	cout<<"**********演讲比赛流程管理系统**********"<<endl;
	cout<<"**********   0.退出比赛程序   **********"<<endl;
	cout<<"**********   1.开始演讲比赛   **********"<<endl;
	cout<<"**********   2.查看往届记录   **********"<<endl;
	cout<<"**********   3.清空比赛记录   **********"<<endl;
	cout<<"****************************************"<<endl;
	cout<<endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

main.cpp中通过实例化对象调用该函数接口的代码如下。

speechManager sp;
sp.show_menu();  //显示菜单
  • 1
  • 2

运行程序后的结果如下图所示。
在这里插入图片描述


二、退出管理系统

speechManager.cpp中实现退出管理系统的代码如下。

void speechManager::exit_system()  //退出系统
{
	cout<<"欢迎下次使用!"<<endl;
	system("pause");
	exit(0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

main.cpp中通过switch-case分支对用户的输入进行不同的处理,到此为止的代码框架如下。

int user_choice;
speechManager sp;
while(1)
{
	sp.show_menu();  //显示菜单
	cout<<"请输入您的选择: ";
	cin>>user_choice;
	switch(user_choice)
	{
	case 0:
		sp.exit_system();  //退出系统
		break;
	case 1:
		
		break;
	case 2:
		
		break;
	case 3:
		
		break;
	default:
		system("cls");  //清屏
		break;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

运行程序之后输入0,按回车后显示如下,再按任意键就会退出该程序。
在这里插入图片描述


三、开始演讲比赛

本案例中内容最多的就是演讲比赛功能,在管理类中添加下面各项属性。

vector<int> v1;  //第一轮比赛12人
vector<int> v2;  //第二轮比赛6人
vector<int> v;  //获胜者3人
map<int,Person> m;  //存放选手和编号的容器
int round;  //比赛轮数
bool fileIsEmpty;  //判断文件是否为空
map<int,vector<string>> m_record;  //读取文件记录
int session;  //记录比赛届数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在speechManager.h中创建选手类如下。

class Person
{
public:
	string name;  //选手姓名
	double score[2];  //记录平均分,有两轮
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在构造函数中初始化各项参数、创建比赛选手、然后从文件中加载往届的记录信息,构造函数的内容如下。

speechManager::speechManager()  //构造函数
{
	init_index();    //初始化各项参数
	read_from_file();  //加载往届记录信息,读取到session供create_person()使用
	create_person();  //创建选手
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

构造函数中调用的各函数如下。

void speechManager::init_index() //初始化
{
	this->v1.clear();  //清空各容器
	this->v2.clear();
	this->v.clear();
	this->m.clear();
	this->round = 1;  //第一轮
	this->m_record.clear();
}

void speechManager::read_from_file()  //从文件读取信息
{
	ifstream ifs("speech.cvs",ios::in);
	if(!ifs.is_open())
	{
		fileIsEmpty = true;
		//cout<<"文件不存在!"<<endl;
		session = 0;  //第0届
		ifs.close();
		return;
	}
	char ch;
	ifs>>ch;  //先读一个字符
	if(ifs.eof())  //文件被清空的情况
	{
		//cout<<"文件为空!"<<endl;
		fileIsEmpty = true;
		session = 0;  //第0届
		ifs.close();
		return;
	}
	fileIsEmpty = false;  //以上两个if都不满足,说明文件有内容
	ifs.putback(ch);   //将上面读取的单个字符放回文件中
	string data;
	int line = 0;    //记录行数,每一行就是一届的信息
	while(ifs>>data)  //逐行读取到data中
	{
		vector<string> vs; //存放拆分后的字符串
		int pos = -1;
		int start = 0;
		while(1)  //拆分字符串
		{
			pos = data.find(",",start);  //从start位置开始找第一个,
			if(pos == -1)
			{
				break;  //没找到
			}
			string temp = data.substr(start,pos-start);   //截取子串
			start = pos + 1;   //移动下一次开始找的位置
			vs.push_back(temp);  //将拆分得到的字符串存入容器中
		}
		this->m_record.insert(make_pair(line,vs));  //将届数和记录存入map容器中
		line++;
		session = line;  //记录届数
		//cout<<line<<" data: "<<data<<endl;
	}
	ifs.close();
}

void speechManager::create_person()  //创建选手
{
	session++;  //届数
	string nameSeed = "ABCDEFGHIJKL";
	for(int i=0;i<nameSeed.size();i++)
	{
		string name = "选手";
		name += nameSeed[i];
		Person p;
		p.name = name;  //姓名
		p.score[0] = 0;  //分数都初始化为0
		p.score[1] = 0;
		v1.push_back(session*10000+1+i);   //根据届数给选手编号,并插入到vector容器中
		m.insert(make_pair<int,Person>(session*10000+1+i,p));  //插入到map容器中
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

正式开始演讲比赛后,分两轮进行,每轮比赛需要进行抽签决定顺序,存放评委打分,显示本轮晋级结果,并在第二轮结束后将本届比赛获胜的三位选手信息写入文件中。

void speechManager::start_speech()  //开始比赛,控制整个流程
{
	//第一轮比赛
	speech_draw(); //1.抽签确定比赛顺序
	speech_contest(); //2.开始比赛并打分
	show_score();  //3.显示晋级结果
	//第二轮比赛
	this->round++;
	speech_draw();  //1.抽签确定比赛顺序
	speech_contest(); //2.开始比赛并打分
	show_score(); //3.显示最终获胜结果
	save_to_file(); //4.保存分数到文件中
	cout<<"本次比赛结束!"<<endl;

	init_index();  //初始化各项参数
	read_from_file();  //加载往届记录信息
	create_person();  //创建选手

	system("pause");
	system("cls");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

演讲比赛过程中用到的各个函数如下。

void speechManager::speech_draw()   //抽签
{
	cout<<"-----------------------"<<endl;
	cout<<"第"<<this->round<<"轮比赛选手正在抽签..."<<endl;
	cout<<"-----------------------"<<endl;
	cout<<"抽签后的演讲顺序如下: "<<endl;
	if(this->round == 1)  //第一轮抽签
	{
		random_shuffle(v1.begin(),v1.end());   //洗牌,打乱v1容器中的编号顺序
		for(vector<int>::iterator i=v1.begin();i!=v1.end();i++)
		{
			cout<<*i<<" ";
		}
		cout<<endl;
	}
	else   //第二轮抽签
	{
		random_shuffle(v2.begin(),v2.end());   //洗牌,打乱v2容器中的编号顺序
		for(vector<int>::iterator i=v2.begin();i!=v2.end();i++)
		{
			cout<<*i<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
	system("pause");
	cout<<endl;
}

void speechManager::speech_contest()  //开始比赛并打分
{
	cout<<"------------ 第"<<this->round<<"轮比赛开始 ------------"<<endl;
	multimap<double,int,greater<double>> group;  //防止同分情况定义为multimap容器,降序排列6个人的成绩和编号
	//这里把得分放在编号前面是为了降序排列得分,map容器是按照第一个位置的参数排序的
	int num = 0;    //记录小组内成员个数,6人一组
	vector<int> vtemp;  //创建一个临时容器,根据当前比赛轮数进行拷贝操作
	if(this->round == 1)
	{
		vtemp = v1;  //第一轮
	}
	else
	{
		vtemp = v2;   //第二轮
	}
	for(vector<int>::iterator i=vtemp.begin();i!=vtemp.end();i++)
	{
		num++;
		deque<double> d;  //存取评委打分,deque容器排序后容易去掉开头末尾两数
		for(int j=0;j<10;j++)
		{
			double score = (rand()%401+600)/10.f;  //60.0-100.0
			d.push_back(score);
		}
		sort(d.begin(),d.end(),greater<double>());  //降序排列
		d.pop_front();  //去除最高分
		d.pop_back();  //去除最低分
		double aver = accumulate(d.begin(),d.end(),0.0f) / (double) d.size();  //累加总分并求平均分
		this->m[*i].score[round-1] = aver;  //将平均分存放在map容器中
		//cout<<"编号: "<<*i<<" 姓名: "<<m[*i].name<<" 平均分: "<<m[*i].score[round-1]<<endl;
		group.insert(make_pair<double,int>(aver,*i));   //插入临时容器中,key是得分,value是选手编号
		if(num % 6 == 0)  //num = 6 或 num = 12 时进入
		{
			cout<<"********** 第"<<num/6<<"小组的排名如下 **********"<<endl;
			int count = 0;
			for(multimap<double,int,greater<double>>::iterator i=group.begin();i!=group.end();i++)
			{
				cout<<"编号: "<<i->second<<" 姓名: "<<m[i->second].name<<" 平均分: "<<m[i->second].score[round-1]<<endl;
				if(count < 3)  //取前三名
				{
					if(this->round == 1)
					{
						v2.push_back(i->second);  //晋级第二轮的选手
					}
					else
					{
						v.push_back(i->second);  //最终获胜的选手
					}
					count++;
				}
			}
			group.clear();  //每6人就清空一次容器
		}
	}
	cout<<"------------ 第"<<this->round<<"轮比赛结束 ------------"<<endl;
	cout<<endl;
	system("pause");
	cout<<endl;
}

void speechManager::show_score()  //显示晋级结果
{
	cout<<"-------- 第"<<this->round<<"轮晋级选手信息如下 --------"<<endl;
	vector<int> vtemp;  //创建一个临时容器,根据当前比赛轮数进行拷贝操作
	if(this->round == 1)
	{
		vtemp = v2;
	}
	else
	{
		vtemp = v;
	}
	for(vector<int>::iterator i=vtemp.begin();i!=vtemp.end();i++)
	{
		cout<<"编号: "<<*i<<" 姓名: "<<m[*i].name<<" 平均分: "<<m[*i].score[round-1]<<endl;
	}
	cout<<"---------------------------------------"<<endl;
	cout<<endl;
	system("pause");
	system("cls");
	show_menu();
}

void speechManager::save_to_file()  //将晋级信息保存到文件
{
	ofstream ofs;
	ofs.open("speech.cvs",ios::out | ios::app);   //用追加的方式往文件中写数据
	for(vector<int>::iterator i=v.begin();i!=v.end();i++)
	{
		ofs<<*i<<","<<m[*i].score[1]<<",";
	}
	ofs<<endl;
	ofs.close();
	cout<<"数据已保存!"<<endl;
	fileIsEmpty = false;   //插入数据后文件已经不为空
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125

抽签过程如下图所示。
在这里插入图片描述
第一轮比赛结束后,每个小组按照得分从高到低排列,每个小组取前三名晋级下一轮,如下图所示。
在这里插入图片描述
第二轮抽签、赛果及晋级信息如下图所示。
在这里插入图片描述
本次比赛结束后将获胜三人的信息存入文件中,方便后续访问。
在这里插入图片描述


四、查看往届记录

read_from_file()函数中已经将文件中保存的记录读取到了map容器中,现在查看往届记录只需要从map容器中读取信息即可。
查看往届记录的函数体如下。

void speechManager::show_record()  //显示往届记录
{
	if(fileIsEmpty)
	{
		cout<<"文件为空或不存在!"<<endl;
	}
	else
	{
		for(int i=0;i<m_record.size();i++)
		{
			cout<<"第"<<i+1<<"届---冠军编号:"<<m_record[i][0]<<" 分数:"<<m_record[i][1]
				<<"   亚军编号:"<<m_record[i][2]<<" 分数:"<<m_record[i][3]
				<<"   季军编号:"<<m_record[i][4]<<" 分数:"<<m_record[i][5]<<endl;
		}
		/*for(map<int,vector<string>>::iterator i=m_record.begin();i!=m_record.end();i++)
		{
			cout<<"第"<<i->first+1<<"届---冠军编号:"<<i->second[0]<<" 分数:"<<i->second[1]
				<<"   亚军编号:"<<i->second[2]<<" 分数:"<<i->second[3]
				<<"   季军编号:"<<i->second[4]<<" 分数:"<<i->second[5]<<endl;
		}*/
	}
	system("pause");
	system("cls");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

读取往届记录信息的截图如下图所示。
在这里插入图片描述
往届记录在项目工程文件夹下的speech.cvs文件中存放的信息如下。
在这里插入图片描述


五、清空比赛记录

清空比赛记录前让用户再确认一次,确认无误后将存取记录的文件删空,这样以往的比赛记录就不存在了,同时还要执行构造函数中执行的几个函数进行初始化操作。
清空比赛记录的函数体如下。

void speechManager::clear_record()  //清空往届记录
{
	if(fileIsEmpty)
	{
		cout<<"文件为空!"<<endl;
	}
	else
	{
		cout<<"确定清空文件?"<<endl;
		cout<<"输入 1---确定"<<endl;
		cout<<"其他键---取消"<<endl;
		int input = 0;
		cin>>input;
		if(input == 1)
		{
			ofstream ofs("speech.cvs",ios::trunc);  //删除文件并重新创建同名文件
			ofs.close();

			init_index();    //初始化各项参数
			session = 0;  //第0届
			create_person();  //创建选手
			read_from_file();  //加载往届记录信息
			cout<<"清空往届比赛记录成功!"<<endl;
		}
	}
	system("pause");
	system("cls");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

清空比赛记录的操作截图如下图所示。
在这里插入图片描述
再次查看往届记录,提示文件为空或不存在,打开文件,里面的内容也被清空了,如下图所示。
在这里插入图片描述


六、案例源代码

speechManager.h文件的代码如下。

#pragma once
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <functional>
#include <numeric>
#include <deque>
#include <fstream>
using namespace std;

class Person
{
public:
	string name;  //选手姓名
	double score[2];  //记录平均分,有两轮
};

class speechManager
{
public:
	speechManager();  //构造函数
	void show_menu();  //显示菜单
	void exit_system();  //退出系统
	void init_index();  //初始化
	void create_person();  //创建选手
	void start_speech();  //开始比赛,控制整个流程
	void speech_draw();  //抽签
	void speech_contest();  //开始比赛并打分
	void show_score();  //显示晋级结果
	void save_to_file();  //将晋级信息保存到文件
	void read_from_file();  //从文件读取信息
	void show_record();  //显示往届记录
	void clear_record();  //清空往届记录
	~speechManager();  //析构函数

	vector<int> v1;  //第一轮比赛12人
	vector<int> v2;  //第二轮比赛6人
	vector<int> v;  //获胜者3人
	map<int,Person> m;  //存放选手和编号的容器
	int round;  //比赛轮数
	bool fileIsEmpty;  //判断文件是否为空
	map<int,vector<string>> m_record;  //读取文件记录
	int session;  //记录比赛届数
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

speechManager.cpp文件的代码如下。

#include "speechManager.h"

speechManager::speechManager()  //构造函数
{
	init_index();    //初始化各项参数
	read_from_file();  //加载往届记录信息,读取到session供create_person()使用
	create_person();  //创建选手
}

void speechManager::show_menu()  //显示菜单
{
	cout<<"****************************************"<<endl;
	cout<<"**********演讲比赛流程管理系统**********"<<endl;
	cout<<"**********   0.退出比赛程序   **********"<<endl;
	cout<<"**********   1.开始演讲比赛   **********"<<endl;
	cout<<"**********   2.查看往届记录   **********"<<endl;
	cout<<"**********   3.清空比赛记录   **********"<<endl;
	cout<<"****************************************"<<endl;
	cout<<endl;
}

void speechManager::exit_system()  //退出系统
{
	cout<<"欢迎下次使用!"<<endl;
	system("pause");
	exit(0);
}

void speechManager::init_index() //初始化
{
	this->v1.clear();  //清空各容器
	this->v2.clear();
	this->v.clear();
	this->m.clear();
	this->round = 1;  //第一轮
	this->m_record.clear();
}

void speechManager::create_person()  //创建选手
{
	session++;  //届数
	string nameSeed = "ABCDEFGHIJKL";
	for(int i=0;i<nameSeed.size();i++)
	{
		string name = "选手";
		name += nameSeed[i];
		Person p;
		p.name = name;  //姓名
		p.score[0] = 0;  //分数都初始化为0
		p.score[1] = 0;
		v1.push_back(session*10000+1+i);   //根据届数给选手编号,并插入到vector容器中
		m.insert(make_pair<int,Person>(session*10000+1+i,p));  //插入到map容器中
	}
}

void speechManager::speech_draw()   //抽签
{
	cout<<"-----------------------"<<endl;
	cout<<"第"<<this->round<<"轮比赛选手正在抽签..."<<endl;
	cout<<"-----------------------"<<endl;
	cout<<"抽签后的演讲顺序如下: "<<endl;
	if(this->round == 1)  //第一轮抽签
	{
		random_shuffle(v1.begin(),v1.end());   //洗牌,打乱v1容器中的编号顺序
		for(vector<int>::iterator i=v1.begin();i!=v1.end();i++)
		{
			cout<<*i<<" ";
		}
		cout<<endl;
	}
	else   //第二轮抽签
	{
		random_shuffle(v2.begin(),v2.end());   //洗牌,打乱v2容器中的编号顺序
		for(vector<int>::iterator i=v2.begin();i!=v2.end();i++)
		{
			cout<<*i<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
	system("pause");
	cout<<endl;
}

void speechManager::speech_contest()  //开始比赛并打分
{
	cout<<"------------ 第"<<this->round<<"轮比赛开始 ------------"<<endl;
	multimap<double,int,greater<double>> group;  //防止同分情况定义为multimap容器,降序排列6个人的成绩和编号
	//这里把得分放在编号前面是为了降序排列得分,map容器是按照第一个位置的参数排序的
	int num = 0;    //记录小组内成员个数,6人一组
	vector<int> vtemp;  //创建一个临时容器,根据当前比赛轮数进行拷贝操作
	if(this->round == 1)
	{
		vtemp = v1;  //第一轮
	}
	else
	{
		vtemp = v2;   //第二轮
	}
	for(vector<int>::iterator i=vtemp.begin();i!=vtemp.end();i++)
	{
		num++;
		deque<double> d;  //存取评委打分,deque容器排序后容易去掉开头末尾两数
		for(int j=0;j<10;j++)
		{
			double score = (rand()%401+600)/10.f;  //60.0-100.0
			d.push_back(score);
		}
		sort(d.begin(),d.end(),greater<double>());  //降序排列
		d.pop_front();  //去除最高分
		d.pop_back();  //去除最低分
		double aver = accumulate(d.begin(),d.end(),0.0f) / (double) d.size();  //累加总分并求平均分
		this->m[*i].score[round-1] = aver;  //将平均分存放在map容器中
		//cout<<"编号: "<<*i<<" 姓名: "<<m[*i].name<<" 平均分: "<<m[*i].score[round-1]<<endl;
		group.insert(make_pair<double,int>(aver,*i));   //插入临时容器中,key是得分,value是选手编号
		if(num % 6 == 0)  //num = 6 或 num = 12 时进入
		{
			cout<<"********** 第"<<num/6<<"小组的排名如下 **********"<<endl;
			int count = 0;
			for(multimap<double,int,greater<double>>::iterator i=group.begin();i!=group.end();i++)
			{
				cout<<"编号: "<<i->second<<" 姓名: "<<m[i->second].name<<" 平均分: "<<m[i->second].score[round-1]<<endl;
				if(count < 3)  //取前三名
				{
					if(this->round == 1)
					{
						v2.push_back(i->second);  //晋级第二轮的选手
					}
					else
					{
						v.push_back(i->second);  //最终获胜的选手
					}
					count++;
				}
			}
			group.clear();  //每6人就清空一次容器
		}
	}
	cout<<"------------ 第"<<this->round<<"轮比赛结束 ------------"<<endl;
	cout<<endl;
	system("pause");
	cout<<endl;
}

void speechManager::show_score()  //显示晋级结果
{
	cout<<"-------- 第"<<this->round<<"轮晋级选手信息如下 --------"<<endl;
	vector<int> vtemp;  //创建一个临时容器,根据当前比赛轮数进行拷贝操作
	if(this->round == 1)
	{
		vtemp = v2;
	}
	else
	{
		vtemp = v;
	}
	for(vector<int>::iterator i=vtemp.begin();i!=vtemp.end();i++)
	{
		cout<<"编号: "<<*i<<" 姓名: "<<m[*i].name<<" 平均分: "<<m[*i].score[round-1]<<endl;
	}
	cout<<"---------------------------------------"<<endl;
	cout<<endl;
	system("pause");
	system("cls");
	show_menu();
}

void speechManager::save_to_file()  //将晋级信息保存到文件
{
	ofstream ofs;
	ofs.open("speech.cvs",ios::out | ios::app);   //用追加的方式往文件中写数据
	for(vector<int>::iterator i=v.begin();i!=v.end();i++)
	{
		ofs<<*i<<","<<m[*i].score[1]<<",";
	}
	ofs<<endl;
	ofs.close();
	cout<<"数据已保存!"<<endl;
	fileIsEmpty = false;   //插入数据后文件已经不为空
}

void speechManager::start_speech()  //开始比赛,控制整个流程
{
	//第一轮比赛
	speech_draw(); //1.抽签确定比赛顺序
	speech_contest(); //2.开始比赛并打分
	show_score();  //3.显示晋级结果
	//第二轮比赛
	this->round++;
	speech_draw();  //1.抽签确定比赛顺序
	speech_contest(); //2.开始比赛并打分
	show_score(); //3.显示最终获胜结果
	save_to_file(); //4.保存分数到文件中
	cout<<"本次比赛结束!"<<endl;

	init_index();  //初始化各项参数
	read_from_file();  //加载往届记录信息
	create_person();  //创建选手

	system("pause");
	system("cls");
}

void speechManager::read_from_file()  //从文件读取信息
{
	ifstream ifs("speech.cvs",ios::in);
	if(!ifs.is_open())
	{
		fileIsEmpty = true;
		//cout<<"文件不存在!"<<endl;
		session = 0;  //第0届
		ifs.close();
		return;
	}
	char ch;
	ifs>>ch;  //先读一个字符
	if(ifs.eof())  //文件被清空的情况
	{
		//cout<<"文件为空!"<<endl;
		fileIsEmpty = true;
		session = 0;  //第0届
		ifs.close();
		return;
	}
	fileIsEmpty = false;  //以上两个if都不满足,说明文件有内容
	ifs.putback(ch);   //将上面读取的单个字符放回文件中
	string data;
	int line = 0;    //记录行数,每一行就是一届的信息
	while(ifs>>data)  //逐行读取到data中
	{
		vector<string> vs; //存放拆分后的字符串
		int pos = -1;
		int start = 0;
		while(1)  //拆分字符串
		{
			pos = data.find(",",start);  //从start位置开始找第一个,
			if(pos == -1)
			{
				break;  //没找到
			}
			string temp = data.substr(start,pos-start);   //截取子串
			start = pos + 1;   //移动下一次开始找的位置
			vs.push_back(temp);  //将拆分得到的字符串存入容器中
		}
		this->m_record.insert(make_pair(line,vs));  //将届数和记录存入map容器中
		line++;
		session = line;  //记录届数
		//cout<<line<<" data: "<<data<<endl;
	}
	ifs.close();
}

void speechManager::show_record()  //显示往届记录
{
	if(fileIsEmpty)
	{
		cout<<"文件为空或不存在!"<<endl;
	}
	else
	{
		//for(int i=0;i<m_record.size();i++)
		//{
		//	cout<<"第"<<i+1<<"届---冠军编号:"<<m_record[i][0]<<" 分数:"<<m_record[i][1]
		//		<<"   亚军编号:"<<m_record[i][2]<<" 分数:"<<m_record[i][3]
		//		<<"   季军编号:"<<m_record[i][4]<<" 分数:"<<m_record[i][5]<<endl;
		//}
		for(map<int,vector<string>>::iterator i=m_record.begin();i!=m_record.end();i++)
		{
			cout<<"第"<<i->first+1<<"届---冠军编号:"<<i->second[0]<<" 分数:"<<i->second[1]
				<<"   亚军编号:"<<i->second[2]<<" 分数:"<<i->second[3]
				<<"   季军编号:"<<i->second[4]<<" 分数:"<<i->second[5]<<endl;
		}
	}
	system("pause");
	system("cls");
}

void speechManager::clear_record()  //清空往届记录
{
	if(fileIsEmpty)
	{
		cout<<"文件为空!"<<endl;
	}
	else
	{
		cout<<"确定清空文件?"<<endl;
		cout<<"输入 1---确定"<<endl;
		cout<<"其他键---取消"<<endl;
		int input = 0;
		cin>>input;
		if(input == 1)
		{
			ofstream ofs("speech.cvs",ios::trunc);  //删除文件并重新创建同名文件
			ofs.close();

			init_index();    //初始化各项参数
			session = 0;  //第0届
			create_person();  //创建选手
			read_from_file();  //加载往届记录信息
			cout<<"清空往届比赛记录成功!"<<endl;
		}
	}
	system("pause");
	system("cls");
}

speechManager::~speechManager()  //析构函数
{

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310

main.cpp文件的代码如下。

#include <ctime>
#include "speechManager.h"
using namespace std;

int main()
{
	srand((unsigned int)time(NULL));   //随机数种子
	int user_choice;  //用户选择
	speechManager sp;  //实例化对象
	while(1)
	{
		sp.show_menu();   //显示菜单
		cout<<"请输入您的选择: ";
		cin>>user_choice;
		switch(user_choice)
		{
		case 0:
			sp.exit_system();  //退出系统
			break;
		case 1:
			sp.start_speech();  //开始演讲比赛
			break;
		case 2:
			sp.show_record();  //查看往届记录
			break;
		case 3: 
			sp.clear_record();  //清空比赛记录
			break;
		default:
			system("cls");  //清屏
			break;
		}
	}
	system("pause");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

本文参考视频:
黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/260757
推荐阅读
相关标签
  

闽ICP备14008679号