C/C++教程

C++入门——演讲比赛流程管理系统

本文主要是介绍C++入门——演讲比赛流程管理系统,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

参考链接

  1. https://www.bilibili.com/video/BV1et411b73Z?p=264

演讲比赛流程管理系统

演讲比赛程序需求

比赛规则

  1. 学校举行一场演讲比赛,共有12个人参加。比赛共两轮,第一轮为淘汰赛,第二轮为决赛
  2. 每名选手都有对应的编号,如10001-10012
  3. 比赛方式:分组比赛,每组6个人
  4. 第一轮分为两个小组,整体按照选手编号进行抽签后顺序演讲
  5. 十个评委分别给每名选手打分,去除最高分和最低分,求的平均分为本轮选手的成绩
  6. 当小组演讲完后,淘汰组内排名最后的三个选手,前三名晋级,进入下一轮的比赛
  7. 第二轮为决赛,前三名胜出
  8. 每轮比赛过后需要显示晋级选手的信息

程序功能

  1. 开始演讲比赛:完成整届比赛的流程,每个比赛阶段需要给用户一个提示,用户按任意键后继续下一个阶段
  2. 查看往届记录:查看之前比赛前三名结果,每次比赛都会记录到文件中,文件用.csv后缀名保存
  3. 清空比赛记录:将文件中数据清空
  4. 退出比赛程序:可以退出当前程序

创建管理类

功能描述

  1. 提供菜单界面与用户交互
  2. 对演讲比赛流程进行控制
  3. 与文件的读写交互

创建文件

在头文件和源文件的文件夹下分别创建speechManager.h和speechManager.cpp文件

class SpeechManager
{
public:
    // 构造函数
    SpeechManager();
    // 析构函数
    ~SpeechManager();
};
#include "speechManager.h"

// 构造函数
SpeechManager::SpeechManager()
{

}
// 析构函数
SpeechManager::~SpeechManager()
{
    
}

菜单功能

添加成员函数

在管理类speechManager.h中添加成员函数void show_Menu();

// 菜单功能
void show_Menu();

菜单功能实现

在管理类speechManager.cpp中实现show_Menu()函数

// 菜单功能
void SpeechManager::show_Menu()
{
    cout << "*****************************************" << endl;
    cout << "***********  欢迎参加演讲比赛  ************" << endl;
    cout << "***********  1.开始演讲比赛  **************" << endl;
    cout << "***********  2.查看往届记录  **************" << endl;
    cout << "***********  3.清空比赛记录  **************" << endl;
    cout << "***********  0.退出比赛程序  **************" << endl;
    cout << endl;
}

测试菜单功能

在演讲比赛流程管理系统.cpp中测试菜单功能

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

int main()
{
    // 创建管理类
    SpeechManager sm;

    sm.show_Menu();

    system("pause");
    return 0;
}

退出功能

提供功能接口

在main函数中提供分支选择,提供每个功能接口

int main()
{
    // 创建管理类
    SpeechManager sm;

    int choice = 0; // 用来存储用户的选项

    while (true)
    {
        sm.show_Menu();

        cout << "请输入您的选择:" << endl;
        cin >> choice; // 接受用户的选项

        switch (choice)
        {
            case 1: // 开始比赛
                break;
            case 2: // 查看记录
                break;
            case 3: // 清空记录
                break;
            case 0: // 退出系统
                break;
            default:
                system("cls"); // 清屏
                break;
        }
    }

    system("pause");
    return 0;
}

实现退出功能

在speechManager.h中提供退出系统的成员函数void exitSystem();
在speechManager.cpp中提供具体的功能实现

void SpeechManager::exitSystem()
{
    cout << "欢迎下次使用" << endl;
    system("pause");
    exit(0);
}

演讲比赛功能

功能分析

比赛流程分析:
抽签–>开始演讲比赛–>显示第一轮比赛结果–>
抽签–>开始演讲比赛–>显示前三名结果–>保存分数

创建选手类

选手类中的属性包含:选手姓名、分数
头文件中创建speaker.h文件,并添加代码:

class Speaker
{
public:
    string m_Name; // 姓名
    double m_Score[2]; // 分数 最多有两轮得分
};

比赛

成员属性添加

在speechManager.h中添加属性

// 比赛选手 容器  12人
vector<int> v1;

// 第一轮晋级容器  6人
vector<int> v2;

//胜利前三名容器  3人
vector<int> vVictory;

// 存放编号以及对应的具体选手
map<int, Speaker> m_Speaker;

// 记录比赛轮数
int m_Index;
初始化属性

在speechManager.h中提供开始比赛的成员函数void initSpeech();

//初始化属性
void initSpeech();

在speechManager.cpp中实现void initSpeech();

void SpeechManager::initSpeech()
{
    // 容器保证为空
    this->v1.clear();
    this->v2.clear();
    this->vVictory.clear();
    this->m_Speaker.clear();
    //初始化比赛轮数
    this->m_Index = 1;
}

SpeechManager构造函数中调用void initSpeech();

SpeechManager::SpeechManager()
{
    // 初始化属性
    this->initSpeech();
}
创建选手

在speechManager.h中提供开始比赛的成员函数void createSpeaker();

// 初始化创建12名选手
void createSpeaker();

在speechManager.cpp中实现void createSpeaker();

void SpeechManager::createSpeaker()
{
    string nameSeed = "ABCDEFGHIJKL";
    for (int i = 0; i < nameSeed.size(); i++)
    {
        string name = "选手";
        name += nameSeed[i];

        Speaker sp;
        sp.m_Name = name;
        for (int j = 0; j < 2; i++)
        {
            sp.m_Score[i] = 0;
        }

        // 12名选手编号
        this->v1.push_pack(i + 10001);

        // 选手编号以及对应的选手存放到map容器中
        this->m_Speaker.insert(make_pair(i + 10001, sp));
    }
}

SpeechManager类的构造函数中调用void createSpeaker();

SpeechManager::SpeechManager()
{
    // 初始化属性
    this->initSpeech();

    // 创建选手
    this->createSpeaker();
}
开始比赛成员函数添加

在speechManager.h中提供开始比赛的成员函数void startSpeech();
该函数功能是控制比赛的流程

// 开始比赛-比赛流程控制
void startSpeech();

在speechManager.cpp中将startSpeech的空实现先写入

void SpeechManager::startSpeech()
{
    // 第一轮比赛
    // 1. 抽签

    // 2. 比赛

    // 3. 显示晋级结果

    // 第二轮比赛
    // 1. 抽签

    // 2. 比赛

    // 3. 显示最终结果

    // 4. 保存分数

}
抽签

在speechManager.h中提供抽签的成员函数void speechDraw();

// 抽签
void speechDraw();

在speechManager.cpp中实现成员函数void speechDraw();

void SpeechManager::speechDraw()
{
    cout << "第 << " << this->m_Index << " >> 轮比赛选手正在抽签" << endl;
    cout << "----------------------" << endl;
    cout << "抽签后演讲顺序如下:" << endl;
    if (this->m_Index == 1)
    {
        random_shuffle(v1.begin(), v1.end());
        for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    else
    {
        random_shuffle(v2.begin(), v2.end());
        for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    cout << "--------------------" << endl;
    system("pause");
    cout << endl;
}

在startSpeech比赛流程控制的函数中,调用抽签函数

// 1. 抽签
speechDraw();

在main函数中,分支1选项中,调用开始比赛的接口

case 1: // 开始比赛
    sm.startSpeech();
    break;
开始比赛

在speechManager.h中提供比赛的成员函数void speechContest();

// 比赛
void speechContest();

在speechManager.cpp中实现成员函数void speechContest();

void SpeechManager::speechContest()
{
    cout << "--------------第" << this->m_Index << "轮正式比赛开始: --------------" << endl;

    multimap<double, int, greater<double>> groupScore; // 临时容器,保存key分数 value选手编号

    int num = 0; // 记录人员数,6个为1组

    vector<int> v_Src; // 比赛的人员容器
    if (this->m_Index == 1)
    {
        v_Src = v1;
    }
    else
    {
        v_Src = v2;
    }

    // 遍历所有参数选手
    for (vector<int>::iterator it = v_Src.begin(); it != v_Src.end(); it++)
    {
        num++;

        // 评委打分
        deque<double> d;
        for (int i = 0; i < 10; i++)
        {
            double score = (rand() % 401 + 600) / 10.f; // 600~1000
            d.push_back(score);
        }

        sort(d.begin(), d.end(), greater<double>());
        d.pop_front();
        d.pop_back();

        double sum = accumulate(d.begin(), d.end(), 0.0f);
        double avg = sum / (double)d.size();

        // 每个人平均分
        this->m_Speaker[*it].m_Score[this->m_Index - 1] = avg;

        // 6个人一组,用临时容器保存
        groupScore.insert(make_pair(avg, *it));
        if (num % 6 == 0)
        {
            cout << "第" << num / 6 << "小组比赛名次: " << endl;
            for (multimap<double, int, greater<double>>::iterator it = groupScore.begin(); it != groupScore.end(); it++)
            {
                cout << "编号:" << it->second << "姓名:" << this->m_Speaker[it->second].m_Name << " 成绩:" << this->m_Speaker[it->second].m_Score[this->m_Index - 1] << endl;
            }

            int count = 0;
            // 取前三名
            for (multimap<double, int, greater<double>>::iterator it = groupScore.begin(); it != groupScore.end() && count < 3; it++, count++)
            {
                if (this->m_Index == 1)
                {
                    v2.push_back((*it).second);
                }
                else
                {
                    vVictory.push_back((*it).second);
                }
            }

            groupScore.clear();

            cout << endl;
        }
    }
    cout << "-------------- 第" << this->m_Index << "轮比赛完毕 ---------------" << endl;
    system("pause");
}
显示比赛分数

在speechManager.h中提供显示分数的成员函数void showScore();

// 显示比赛结果
void showScore();

在speechManager.cpp中实现成员函数void showScore();

void SpeechManager::showScore()
{
    cout << "-------------- 第" << this->m_Index << "轮晋级选手信息如下:--------------------" << endl;
    vector<int> v;
    if (this->m_Index == 1)
    {
        v = v2;
    }
    else
    {
        v = vVictory;
    }

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << "选手编号:" << *it << "姓名:" << m_Speaker[*it].m_Name << " 得分:" << m_Speaker[*it].m_Score[this->m_Index - 1] << endl;
    }
    cout << endl;

    system("pause");
    system("cls");
    this->show_Menu();
}

在startSpeech比赛流程控制的函数中,调用显示比赛分数函数

第二轮比赛

在startSpeech比赛流程控制的函数中,加入第二轮的流程

void SpeechManager::startSpeech()
{
    // 第一轮比赛
    // 1. 抽签
    this->speechDraw();

    // 2. 比赛
    this->speechContest();

    // 3. 显示晋级结果
    this->showScore();

    // 第二轮比赛
    this->m_Index++;
    // 1. 抽签
    this->speechDraw();

    // 2. 比赛
    this->speechContest();
    
    // 3. 显示最终结果
    this->showScore();

    // 4. 保存分数

}

保存分数

在speechManager.h中添加保存记录的成员函数void saveRecord();

// 保存记录
void saveRecord();

在speechManager.cpp中实现成员函数void saveRecord();

void SpeechManager::saveRecord()
{
    ofstream ofs;
    ofs.open("speech.csv", ios::out | ios::app); // 用输出的方式打开文件

    // 将每个人数据写入到文件中
    for (vector<int>::iterator it = vVictory.begin(); it != vVictory.end(); it++)
    {
        ofs << *it << ","
            << m_Speaker[*it].m_Score[1] << ",";
    }
    ofs << endl;

    // 关闭文件
    ofs.close();

    cout << "记录已经保存" << endl;

    this->fileIsEmpty = false;
}

在startSpeech比赛流程控制的函数中,最后调用保存记录分数函数

// 4. 保存分数
this->saveRecord();

cout << "本届比赛完毕!" << endl;
system("pause");
system("cls");

查看记录

读取记录分数

在speechManager.h中添加读取记录的成员函数void loadRecord();
添加判断文件是否为空的标志bool fileIsEmpty;
添加往届记录的容量map<int, vector> m_Record;

其中m_Record中的key代表第几界,value记录具体的信息

// 读取记录
void loadRecord();

// 文件为空的标志
bool fileIsEmpty;

// 往届记录
map<int, vector<string>> m_Record;

在speechManager.cpp中实现成员函数void_loadRecord();

void SpeechManager::loadRecord()
{
    ifstream ifs("speech.csv", ios:in); // 输入流对象 读取文件

    if (!ifs.is_open())
    {
        this->fileIsEmpty = true;
        cout << "文件不存在!" << endl;
        ifs.close();
        return;
    }

    char ch;
    ifs >> ch;
    if (ifs.eof())
    {
        cout << "文件为空!" << endl;
        this->fileIsEmpty = true;
        ifs.close();
        return;
    }

    // 文件不为空
    this->fileIsEmpty = false;

    ifs.putback(ch); // 读取的单个字符放回去

    string data;
    int index = 0;
    while (ifs >> data)
    {
        vector<string> v;
        int pos = -1;
        int start = 0;

        while (true)
        {
            pos = data.find(",", start); // 从0开始查找','
            if (pos == -1)
            {
                break; // 找不到break返回
            }
            string tmp = data.substr(start, pos - start); //找到了,进行分割
            v.push_back(tmp);
            start = pos + 1;
        }

        this->m_Record.insert(make_pair(index, v));
        index++;
    }

    ifs.close();
}

在SpeechManager构造函数中调用获取往届记录函数

// 获取往届记录
this->loadRecord();

查看记录功能

在speechManager.h中添加保存记录的成员函数void showRecord();

// 显示往届得分
void showRecord();

在speechManager.cpp中实现成员函数void showRecord();

void SpeechManager::showRecord()
{
    if (this->fileIsEmpty)
    {
        cout << "文件为空或文件不存在!" << endl;
    }
    for (int i = 0; i < this->m_Record.size(); i++)
    {
        cout << "第" << i + 1 << "届 " <<
            "冠军编号:" << this->m_Record[i][0] << " 得分:" << this->m_Record[i][1] << " " <<
            "亚军编号: " << this->m_Record[i][2] << " 得分: " << this->m_Record[i][3] << " " <<
            "季军编号: " << this->m_Record[i][4] << " 得分: " << this->m_Record[i][5] << endl;
    }
    system("pause");
    system("cls");
}

清空记录

情况记录功能实现

在speechManager.h中添加保存记录的成员函数void clearRecord();

// 清空记录
void clearRecord();

在speechManager.cpp中实现成员函数void clearRecord();

void SpeechManager::clearRecord()
{
    cout << "确认清空?" << endl;
    cout << "1、确认" << endl;
    cout << "2、返回" << endl;

    int select = 0;
    cin >> select;

    if (select == 1)
    {
        // 打开模式 ios::trunc 如果存在删除文件并重新创建
        ofstream ofs("speech.csv", ios:trunc);
        ofs.close();

        //初始化属性
        this->initSpeech();

        //创建选手
        this->createSpeaker();

        //获取往届记录
        this->loadRecord();

        cout << "清空成功!" << endl;
    }

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

在main函数分支3中,调用清空比赛记录的接口

case 3: // 清空记录
    sm.clearRecord();
    break;
这篇关于C++入门——演讲比赛流程管理系统的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!