【實訓專案】大獎賽計分系統

kewlgrl發表於2015-07-15

完整原始碼:


/*
*版權所有:Copyright (c)2015,煙臺大學計算機與控制工程學院
*All rights reserved.
*
*檔名稱:Competitor.cpp
*檔案標識:無
*內容摘要:該程式碼用於獲取滿足字尾要求的第一個檔案
*其他說明:無
*當前版本:V1.0
*作    者:單昕昕
*完成日期:2015年7月12日
*
*修改記錄:
*修改日期:無。
*版本號:
*修改人:單昕昕
*修改內容:
*/
#include <fstream>   //操作檔案必寫
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <cstdio>
#include <algorithm>
using namespace std;


class Competitor
{
private:
    double grade[100];//先開一個能儲存100個得分的陣列
public:
    int no,rank; //選手編號、排名
    double ave; //選手平均分
    void input_mark(Competitor &competitor,int rater_number,int competitor_number,int min,int max);//輸入各位選手得分,不符合分數範圍的要求重新輸入;並將選手得分自動儲存到目標資料夾
    void sort_allgrade(int rater_number,int competitor_number,Competitor &competitor);//將各位選手的個人得分降序排列,方便看出利用最值進行下一步計算
    void calculate_mark(int max,int min,Competitor &competitor,int delete_number);//計算刪除掉給定數目的最值後選手的平均得分
    void renew(Competitor &Competitor,int change_rater,double change_score);//修改選手得分
    void writedata(int rater_number,Competitor &competitor);//將修改後的選手得分寫入檔案中
    void storage(int rater_number,int competitor_number,Competitor &competitor);//用(二進位制)檔案讀取將各位選手得分、名次和平均分儲存到檔案中
    void output_mark(int rater_number,int competitor_number,Competitor &competitor);//在螢幕上顯示出選手得分
};


class System
{
public:
    int rater_number,competitor_number,delete_number;//分別表示評委的人數、選手的人數、要去掉的最值數目
    int max,min;//分別表示計分範圍的最大值、最小值
    void initialize_work();//函式初始化的選擇功能選單
    void funtion_work();//大獎賽計分系統的選擇功能選單
    void sort_ave(int rater_number,int competitor_number,double s[][2]);//依據各位選手的個人平均分降序排列得出選手名次
    void file_read(int *rater_number,int *competitor_number,int *min,int *max,int *delete_number);//從相關資料夾中讀取資料進行引數的初始化
    void file_write(int *rater_number,int *competitor_number,int *min,int *max,int *delete_number);//輸入相關資料完成對各引數的初始化
    void renew_grade(int *change_competitor,int *change_rater,double *change_score,int min,int max);//修正選手的分數
};


//下面是普通函式
/*
*函式名稱:compare
*功能描述:比較函式。在sort函式中用到,如果第一個引數小於第二個該函式,返回true。
*輸入引數:無
*輸出引數:無
*返回值:無
*其他說明:無
*/
bool compare(int a,int b)
{
    return a>b;   //降序排列,如果改為return a<b,則為升序
}


int main()
{
    int i,j,t;
    System system;
    system.initialize_work();
    cin>>t;
    switch(t)
    {
    case 1:
        system.file_read(&system.rater_number,&system.competitor_number,&system.min,&system.max,&system.delete_number);
        break;
    case 2:
        system.file_write(&system.rater_number,&system.competitor_number,&system.min,&system.max,&system.delete_number);
        break;
    }
    Competitor *competitor=new Competitor[system.competitor_number];//開闢動態陣列
choose://下面是一個功能選單的介面,選擇完畢後會自動回到原來的選單選擇介面
    system.funtion_work();
    cin>>t;//選擇功能
    switch(t)
    {
    case 1:
    {
        cout<<"請輸入選手的成績:"<<endl;
        for(i=0; i<system.competitor_number; ++i)
        {
            competitor[i].no=i;//錄入選手的編號
            cout<<"選手"<<competitor[i].no<<":";
            competitor[i].input_mark(competitor[i],system.rater_number,system.competitor_number,system.min,system.max);//輸入各位選手的得分,同時儲存到score檔案中
        }
        goto choose;
        break;
    }
    case 2://2.在螢幕上顯示所有選手的成績
    {
        for(i=0; i<system.competitor_number; ++i)
        {
            cout<<"選手"<<competitor[i].no<<":";
            competitor[i].output_mark(system.rater_number,system.competitor_number,competitor[i]);
        }
        goto choose;
        break;
    }
    case 3://3.選手成績降序排列
    {
        cout<<"選手成績降序排列如下:"<<endl;
        for(i=0; i<system.competitor_number; ++i)
            competitor[i].sort_allgrade(system.rater_number,system.competitor_number,competitor[i]);
        for(i=0; i<system.competitor_number; ++i)
        {
            cout<<"選手"<<competitor[i].no<<":";
            competitor[i].output_mark(system.rater_number,system.competitor_number,competitor[i]);
        }
        goto choose;
        break;
    }
    case 4://4.選手的最終排名
    {
        cout<<"選手的最終排名為:"<<endl;
        double s[system.competitor_number][2];
        for(i=0; i<system.competitor_number; ++i)
            competitor[i].calculate_mark(system.rater_number,system.competitor_number,competitor[i],system.delete_number);
        for(i=0; i<system.competitor_number; ++i)
        {
            s[i][0]=competitor[i].no;//陣列的第一列是選手編號
            s[i][1]=competitor[i].ave;//陣列的第二列是選手編號
        }
        cout<<endl;
        system.sort_ave(system.rater_number,system.competitor_number,s);
        for(i=0; i<system.competitor_number; ++i)
            for(j=0; j<system.competitor_number; ++j)
                if(s[i][0]==competitor[j].no)
                {
                    competitor[j].rank=i;//錄入選手排名
                    competitor[j].ave=s[i][1];//錄入選手平均分
                }
        goto choose;
        break;
    }
    case 5://5.選手的成績修改
    {
        int change_competitor,change_rater;
        double change_score;
        system.renew_grade(&change_competitor,&change_rater,&change_score,system.min,system.max);
        //cout<<"change_score"<<change_score<<endl;
        for(i=0; i<system.competitor_number; ++i)
            if(change_competitor==i)//先定位到選手
            {
                competitor[i].renew(competitor[i],change_rater,change_score);//再定位到評委
                break;
            }
        for(i=0; i<system.competitor_number; ++i)
            competitor[i].writedata(system.rater_number,competitor[i]);//將更新後的資料存入一個新的檔案
        cout<<"檔案存入成功!請開啟相關檔案檢視!"<<endl;
        goto choose;
        break;
    }
    case 6://6.選手的成績儲存
    {
        for(i=0; i<system.competitor_number; ++i)
            competitor[i].storage(system.rater_number,system.competitor_number,competitor[i]);//分別以ASCII檔案和二進位制檔案的方式存入
        goto choose;
        break;
    }
    case 0://0.釋放記憶體並退出
    {
        delete [] competitor; //刪除整個物件陣列
        break;
    }
    }
    return 0;
}


  /*
  *函式名稱:input_mark
  *功能描述:輸入各位選手得分,不符合分數範圍的要求重新輸入;並將選手得分自動儲存到目標資料夾
  *輸入引數:rater_number-評委人數,competitor_number-選手人數,min-評分範圍最小值,max-評分範圍最大值
  *輸出引數:competitor-類Competitor的物件
  *返回值:無
  *其他說明:含有儲存各選手得分到檔案中的功能
  */
void Competitor::input_mark(Competitor &competitor,int rater_number,int competitor_number,int min,int max)
{
    int i;
    ofstream outfile("competitor_score.txt",ios::app);  //寫入檔案
    if(!outfile)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                //開啟不成功,則提示後退出。
    }
    for(i=0; i<rater_number ; )
    {
        cin>>competitor.grade[i];
        try//異常處理
        {
            if(competitor.grade[i]>=min&&competitor.grade[i]<=max)//檢查分數是否在正確的範圍內
                ++i;
            else
            {
                i--;//不正確就重新輸入成績
                throw competitor.grade[i];
            }
        }
        catch(double)
        {
            cerr<<"分數不在正確的範圍內!"<<endl;
            cerr<<"請檢查並請重新輸入該選手的成績:";
        }
    }
    outfile<<"選手"<<competitor.no<<":"<<'\t';//將選手的成績存到檔案中
    for(i=0; i<rater_number; ++i)
        outfile<<competitor.grade[i]<<'\t';
    outfile<<'\n';
    outfile.close();  //關閉檔案。用完了必須關閉,否則會丟失資料
}


    /*
    *函式名稱:sort_allgrade
    *功能描述:將各位選手的個人得分降序排列,方便看出利用最值進行下一步計算
    *輸入引數:rater_number-評委人數,competitor_number-選手人數
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:這個功能作用不是很大,主要是為了進行去掉最值的計算而設定的
    */
void Competitor::sort_allgrade(int rater_number,int competitor_number,Competitor &competitor)
{
    sort(competitor.grade,competitor.grade+rater_number*competitor_number,compare);//呼叫系統中的sort函式進行將降序排列,方便去掉最值
}


    /*
    *函式名稱:calculate_mark
    *功能描述:計算刪除掉給定數目的最值後選手的平均得分
    *輸入引數:min-評分範圍最小值,max-評分範圍最大值,delete_number-要刪除掉的最值數目
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:無
    */
void Competitor::calculate_mark(int rater_number,int competitor_number,Competitor &competitor,int delete_number)
{
    double sum;
    int i,j;
    for(i=0; i<competitor_number; ++i)
    {
        sum=0;
        for(j=delete_number; j<rater_number-delete_number; ++j)
        {
            sum+=competitor.grade[j];
        }
    }
    competitor.ave=sum/(rater_number-delete_number);//計算選手平均分
    cout<<"選手"<<competitor.no<<",平均分是:"<<(sum/(rater_number-delete_number))<<"分"<<endl;
}


   /*
   *函式名稱:renew
   *功能描述:修改選手得分
   *輸入引數:change_rater-要修改分數所屬的的評委編號,change_score-更新後的分數
   *輸出引數:competitor-類Competitor的物件
   *返回值:無
   *其他說明:無
   */
void Competitor::renew(Competitor &competitor,int change_rater,double change_score)
{
    double *p;//利用指標取地址對相應給定位置的分數進行修改
    p=&competitor.grade[change_rater];
    *p=change_score;
}


   /*
    *函式名稱:writedata
    *功能描述:將修改後的選手得分寫入檔案中
    *輸入引數:rater_number-評委人數
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:寫入一個新的檔案,而不是覆蓋原有的記錄各選手分數的檔案
    */
void Competitor::writedata(int rater_number,Competitor &competitor)
{
    int i;
    ofstream file("summary.txt",ios::app);
    if(!file)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                 //開啟不成功,則提示後退出。
    }
    file<<"選手"<<competitor.no<<":"<<'\t';
    for(i=0; i<rater_number; ++i)
        file<<competitor.grade[i]<<'\t';
    file<<'\n';
    file.close();//關閉檔案
}


    /*
    *函式名稱:storage
    *功能描述:用(二進位制)檔案讀取將各位選手得分、名次和平均分儲存到檔案中
    *輸入引數:rater_number-評委人數,competitor_number-選手人數
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:用兩種方式寫入,ASCII和二進位制
    */
void Competitor::storage(int rater_number,int competitor_number,Competitor &competitor)
{
    int i;
    ofstream file("store.txt",ios::app);//開啟分數檔案
    if(!file)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                //開啟不成功,則提示後退出。
    }
    file<<"選手"<<competitor.no<<":"<<'\t';
    for(i=0; i<rater_number; ++i)
        file<<competitor.grade[i]<<'\t';
    file<<"平均分:"<<competitor.ave;
    file<<'\t';
    file<<"排名:"<<competitor.rank;
    file<<'\n';
    file.close();//關閉檔案
    //以下為二進位制檔案寫入選手排名及其平均得分
    ofstream bfile("binary_store.dat",ios::app|ios::binary);
    if(!bfile)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                //開啟不成功,則提示後退出。
    }
    bfile<<"選手"<<competitor.no<<":"<<'\t';
    bfile.write((char*)&competitor.no, sizeof(int));
    bfile<<":"<<'\t';
    for(i=0; i<rater_number; ++i)
    {
        bfile.write((char*)&competitor.grade[i], sizeof(double));
        bfile<<'\t';
    }
    bfile<<'\n';
    bfile<<"平均分:";
    bfile.write((char*)&competitor.ave, sizeof(double));
    bfile<<'\t';
    bfile<<"排名:";
    bfile.write((char*)&competitor.rank, sizeof(int));
    bfile<<'\n';
    bfile.close();//關閉檔案
}


    /*
    *函式名稱:output_mark
    *功能描述:在螢幕上顯示出選手得分
    *輸入引數:rater_number-評委人數,competitor_number-選手人數
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:無
    */
void Competitor::output_mark(int rater_number,int n,Competitor &competitor)
{
    int i;
    for(i=0; i<rater_number; ++i)
        cout<<competitor.grade[i]<<'\t';
    cout<<endl;
}


    /*
    *函式名稱:initialize_work
    *功能描述:函式初始化的選擇功能選單
    *輸入引數:無
    *輸出引數:無
    *返回值:無
    *其他說明:無
    */
void System::initialize_work()
{
    cout<<"程式初始化中..."<<endl;//以下先給各引數賦值
    cout<<"給引數初始化的方式..."<<endl;
    cout<<"1.從檔案讀取"<<endl;
    cout<<"2.手動輸入"<<endl;
    cout<<"請選擇:";
}


   /*
   *函式名稱:funtion_work
   *功能描述:大獎賽計分系統的選擇功能選單
   *輸入引數:無
   *輸出引數:無
   *返回值:無
   *其他說明:無
   */
void System::funtion_work()
{
    cout<<"                                ———————————"<<endl;
    cout<<"                                歡迎使用大獎賽計分系統"<<endl;
    cout<<"                                ———————————"<<endl;
    cout<<"                                | "<<"1.輸入選手的成績  "<<" |"<<endl;
    cout<<"                                | "<<"2.所有選手的成績  "<<" |"<<endl;
    cout<<"                                | "<<"3.選手成績降序排列"<<" |"<<endl;
    cout<<"                                | "<<"4.選手的最終排名  "<<" |"<<endl;
    cout<<"                                | "<<"5.選手的成績修改  "<<" |"<<endl;
    cout<<"                                | "<<"6.選手的成績儲存  "<<" |"<<endl;
    cout<<"                                | "<<"0.退出            "<<" |"<<endl;
    cout<<"                                ———————————"<<endl;
    cout<<"請選擇:";
}


    /*
    *函式名稱:sort_ave
    *功能描述:依據各位選手的個人平均分降序排列得出選手名次
    *輸入引數:rater_number-評委人數,competitor_number-選手人數
    *輸出引數:s[][2]-只存有選手編號及其平均分
    *返回值:無
    *其他說明:無
    */
void System::sort_ave(int rater_number,int competitor_number,double f[][2])
{
    int i,j,k;
    double t;
    for(j=0; j<=rater_number-1; j++)//根據選手平均分氣泡排序算出排名
        for(i=0; i<rater_number-j-1; i++)
            if (f[i][1]<f[i+1][1])
            {
                t=f[i][1];
                f[i][1]=f[i+1][1];
                f[i+1][1]=t;
                k=f[i][0];
                f[i][0]=f[i+1][0];
                f[i+1][0]=k;
            }
    for(i=0; i<competitor_number; ++i)
    {
        cout<<"第"<<i<<"名:"<<"選手"<<f[i][0]<<endl;
    }
}


    /*
    *函式名稱:file_read
    *功能描述:從相關資料夾中讀取資料進行引數的初始化
    *輸入引數:無
    *輸出引數:rater_number-評委的人數,competitor_number-選手的人數,delete_number-要去掉的最值數目
    min-計分範圍的最小值,max-計分範圍的最大值
    *返回值:無
    *其他說明:無
    */
void System::file_read(int *rater_number,int *competitor_number,int *min,int *max,int *delete_number)
{
    int i;
    int *parameter=new int[5];//parameter陣列用來儲存各項引數
    ifstream infile("mns_read.txt",ios::in); //測試是否成功開啟,開啟失敗時(如要讀的資料檔案不存在)退出
    if(!infile)
    {
        cerr<<"open error!"<<endl;
        abort();
    }
    for(i=0; i<5; ++i)
        infile>>parameter[i];//從檔案中讀取引數
    infile.close(); //讀入完畢一定要關閉檔案
    //用讀取到的引數分別給各項數值賦值
    *rater_number=parameter[0];
    *competitor_number=parameter[1];
    *min=parameter[2];
    *max=parameter[3];
    *delete_number=parameter[4];
    cout<<"評委的人數:"<<*rater_number<<endl;//將檔案中讀取到的各項有關引數顯示在螢幕上
    cout<<"選手的人數:"<<*competitor_number<<endl;
    cout<<"打分範圍:"<<*min<<"-"<<*max<<endl;
    cout<<"要去掉的最值數目:"<<*delete_number<<endl;
    delete [] parameter;
}


    /*
    *函式名稱:file_write
    *功能描述:輸入相關資料完成對各引數的初始化
    *輸入引數:rater_number-評委的人數,competitor_number-選手的人數,delete_number-要去掉的最值數目
    min-計分範圍的最小值,max-計分範圍的最大值
    *輸出引數:rater_number-評委的人數,competitor_number-選手的人數,delete_number-要去掉的最值數目
    min-計分範圍的最小值,max-計分範圍的最大值
    *返回值:無
    *其他說明:各資料會以檔案形式儲存到相關資料夾中
    */
void System::file_write(int *rater_number,int *competitor_number,int *min,int *max,int *delete_number)
{
    int *parameter=new int[5];//parameter陣列用來儲存各項引數
    cout<<"請輸入:"<<endl;//手動輸入各項引數來初始化
    cout<<"評委的人數:";
    cin>>parameter[0];
    cout<<"選手的人數:";
    cin>>parameter[1];
    cout<<"打分範圍(min-max):";
    cin>>parameter[2];
    cin>>parameter[3];
    cout<<"要去掉的最值數目:";
    cin>>parameter[4];
    *rater_number=parameter[0];
    *competitor_number=parameter[1];
    *min=parameter[2];
    *max=parameter[3];
    *delete_number=parameter[4];
    ofstream file("mns_write.txt",ios::out);  //寫入檔案
    if(!file)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                //開啟不成功,則提示後退出。
    }
    file<<"評委的人數:";
    file<<rater_number<<'\n';
    file<<"選手的人數:";
    file<<competitor_number<<'\n';
    file<<"打分範圍:";
    file<<min<<"-"<<max<<'\n';
    file<<"要去掉的最值數目:";
    file<<delete_number<<'\n';
    file.close();
    delete [] parameter;
}


   /*
   *函式名稱:renew_grade
   *功能描述:修正選手的分數
   *輸入引數:change_competitor-選手的編號,change_rater-評委的編號,change_score-修正後的分數
   min-計分範圍的最小值,max-計分範圍的最大值
   *輸出引數:change_score
   *返回值:無
   *其他說明:無
   */
void System::renew_grade(int *change_competitor,int *change_rater,double *change_score,int min,int max)
{
    int cc,cr;
    double cs;
    cout<<"請輸入要修改的選手編號:";
    cin>>cc;
    *change_competitor=cc;
    cout<<"請輸入評委編號:";
    cin>>cr;
    *change_rater=cr;
    cout<<"請輸入要修改後的成績:";
    cin>>cs;
    while(cs<min||cs>max)
    {
        cerr<<"分數不在正確的範圍內!"<<endl;
        cerr<<"請檢查並請重新輸入該選手的成績:";
        cin>>cs;
    }
    *change_score=cs;
}


多檔案組織:


——————主函式——main.cpp


/*
*版權所有:Copyright (c)2015,煙臺大學計算機與控制工程學院
*All rights reserved.
*
*檔名稱:Competitor.cpp
*檔案標識:無
*內容摘要:該程式碼用於獲取滿足字尾要求的第一個檔案
*其他說明:無
*當前版本:V1.0
*作    者:單昕昕
*完成日期:2015年7月12日
*
*修改記錄:
*修改日期:無。
*版本號:
*修改人:單昕昕
*修改內容:
*/
#include <fstream>   //操作檔案必寫
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <cstdio>
#include <algorithm>
#include "competitor.h"
#include "system.h"
using namespace std;

int main()
{
    int i,j,t;
    System system;
    system.initialize_work();
    cin>>t;
    switch(t)
    {
    case 1:
        system.file_read(&system.rater_number,&system.competitor_number,&system.min,&system.max,&system.delete_number);
        break;
    case 2:
        system.file_write(&system.rater_number,&system.competitor_number,&system.min,&system.max,&system.delete_number);
        break;
    }
    Competitor *competitor=new Competitor[system.competitor_number];//開闢動態陣列
choose://下面是一個功能選單的介面,選擇完畢後會自動回到原來的選單選擇介面
    system.funtion_work();
    cin>>t;//選擇功能
    switch(t)
    {
    case 1:
    {
        cout<<"請輸入選手的成績:"<<endl;
        for(i=0; i<system.competitor_number; ++i)
        {
            competitor[i].no=i;//錄入選手的編號
            cout<<"選手"<<competitor[i].no<<":";
            competitor[i].input_mark(competitor[i],system.rater_number,system.competitor_number,system.min,system.max);//輸入各位選手的得分,同時儲存到score檔案中
        }
        goto choose;
        break;
    }
    case 2://2.在螢幕上顯示所有選手的成績
    {
        for(i=0; i<system.competitor_number; ++i)
        {
            cout<<"選手"<<competitor[i].no<<":";
            competitor[i].output_mark(system.rater_number,system.competitor_number,competitor[i]);
        }
        goto choose;
        break;
    }
    case 3://3.選手成績降序排列
    {
        cout<<"選手成績降序排列如下:"<<endl;
        for(i=0; i<system.competitor_number; ++i)
            competitor[i].sort_allgrade(system.rater_number,system.competitor_number,competitor[i]);
        for(i=0; i<system.competitor_number; ++i)
        {
            cout<<"選手"<<competitor[i].no<<":";
            competitor[i].output_mark(system.rater_number,system.competitor_number,competitor[i]);
        }
        goto choose;
        break;
    }
    case 4://4.選手的最終排名
    {
        cout<<"選手的最終排名為:"<<endl;
        double s[system.competitor_number][2];
        for(i=0; i<system.competitor_number; ++i)
            competitor[i].calculate_mark(system.rater_number,system.competitor_number,competitor[i],system.delete_number);
        for(i=0; i<system.competitor_number; ++i)
        {
            s[i][0]=competitor[i].no;//陣列的第一列是選手編號
            s[i][1]=competitor[i].ave;//陣列的第二列是選手編號
        }
        cout<<endl;
        system.sort_ave(system.rater_number,system.competitor_number,s);
        for(i=0; i<system.competitor_number; ++i)
            for(j=0; j<system.competitor_number; ++j)
                if(s[i][0]==competitor[j].no)
                {
                    competitor[j].rank=i;//錄入選手排名
                    competitor[j].ave=s[i][1];//錄入選手平均分
                }
        goto choose;
        break;
    }
    case 5://5.選手的成績修改
    {
        int change_competitor,change_rater;
        double change_score;
        system.renew_grade(&change_competitor,&change_rater,&change_score,system.min,system.max);
        //cout<<"change_score"<<change_score<<endl;
        for(i=0; i<system.competitor_number; ++i)
            if(change_competitor==i)//先定位到選手
            {
                competitor[i].renew(competitor[i],change_rater,change_score);//再定位到評委
                break;
            }
        for(i=0; i<system.competitor_number; ++i)
            competitor[i].writedata(system.rater_number,competitor[i]);//將更新後的資料存入一個新的檔案
        cout<<"檔案存入成功!請開啟相關檔案檢視!"<<endl;
        goto choose;
        break;
    }
    case 6://6.選手的成績儲存
    {
        for(i=0; i<system.competitor_number; ++i)
            competitor[i].storage(system.rater_number,system.competitor_number,competitor[i]);//分別以ASCII檔案和二進位制檔案的方式存入
        goto choose;
        break;
    }
    case 0://0.釋放記憶體並退出
    {
        delete [] competitor; //刪除整個物件陣列
        break;
    }
    }
    return 0;
}







——————標頭檔案——competitor.h


#ifndef COMPETITOR_H_INCLUDED
#define COMPETITOR_H_INCLUDED

class Competitor
{
private:
    double grade[100];//先開一個能儲存100個得分的陣列
public:
    int no,rank; //選手編號、排名
    double ave; //選手平均分
    void input_mark(Competitor &competitor,int rater_number,int competitor_number,int min,int max);//輸入各位選手得分,不符合分數範圍的要求重新輸入;並將選手得分自動儲存到目標資料夾
    void sort_allgrade(int rater_number,int competitor_number,Competitor &competitor);//將各位選手的個人得分降序排列,方便看出利用最值進行下一步計算
    void calculate_mark(int max,int min,Competitor &competitor,int delete_number);//計算刪除掉給定數目的最值後選手的平均得分
    void renew(Competitor &Competitor,int change_rater,double change_score);//修改選手得分
    void writedata(int rater_number,Competitor &competitor);//將修改後的選手得分寫入檔案中
    void storage(int rater_number,int competitor_number,Competitor &competitor);//用(二進位制)檔案讀取將各位選手得分、名次和平均分儲存到檔案中
    void output_mark(int rater_number,int competitor_number,Competitor &competitor);//在螢幕上顯示出選手得分
};

#endif // COMPETITOR_H_INCLUDED






——————標頭檔案——system.h


#ifndef SYSTEM_H_INCLUDED
#define SYSTEM_H_INCLUDED

class System
{
public:
    int rater_number,competitor_number,delete_number;//分別表示評委的人數、選手的人數、要去掉的最值數目
    int max,min;//分別表示計分範圍的最大值、最小值
    void initialize_work();//函式初始化的選擇功能選單
    void funtion_work();//大獎賽計分系統的選擇功能選單
    void sort_ave(int rater_number,int competitor_number,double s[][2]);//依據各位選手的個人平均分降序排列得出選手名次
    void file_read(int *rater_number,int *competitor_number,int *min,int *max,int *delete_number);//從相關資料夾中讀取資料進行引數的初始化
    void file_write(int *rater_number,int *competitor_number,int *min,int *max,int *delete_number);//輸入相關資料完成對各引數的初始化
    void renew_grade(int *change_competitor,int *change_rater,double *change_score,int min,int max);//修正選手的分數
};

#endif // SYSTEM_H_INCLUDED





——————類實現——competitor.cpp


#include <iostream>
#include <fstream>
#include <cstdlib>
#include "competitor.h"
#include <algorithm>
using namespace std;

//下面是普通函式
/*
*函式名稱:compare
*功能描述:比較函式。在sort函式中用到,如果第一個引數小於第二個該函式,返回true。
*輸入引數:無
*輸出引數:無
*返回值:無
*其他說明:無
*/
bool compare(int a,int b)
{
    return a>b;   //升序排列,如果改為return a<b,則為降序
}

  /*
  *函式名稱:input_mark
  *功能描述:輸入各位選手得分,不符合分數範圍的要求重新輸入;並將選手得分自動儲存到目標資料夾
  *輸入引數:rater_number-評委人數,competitor_number-選手人數,min-評分範圍最小值,max-評分範圍最大值
  *輸出引數:competitor-類Competitor的物件
  *返回值:無
  *其他說明:含有儲存各選手得分到檔案中的功能
  */
void Competitor::input_mark(Competitor &competitor,int rater_number,int competitor_number,int min,int max)
{
    int i;
    ofstream outfile("competitor_score.txt",ios::app);  //寫入檔案
    if(!outfile)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                //開啟不成功,則提示後退出。
    }
    for(i=0; i<rater_number ; )
    {
        cin>>competitor.grade[i];
        try//異常處理
        {
            if(competitor.grade[i]>=min&&competitor.grade[i]<=max)//檢查分數是否在正確的範圍內
                ++i;
            else
            {
                i--;//不正確就重新輸入成績
                throw competitor.grade[i];
            }
        }
        catch(double)
        {
            cerr<<"分數不在正確的範圍內!"<<endl;
            cerr<<"請檢查並請重新輸入該選手的成績:";
        }
    }
    outfile<<"選手"<<competitor.no<<":"<<'\t';//將選手的成績存到檔案中
    for(i=0; i<rater_number; ++i)
        outfile<<competitor.grade[i]<<'\t';
    outfile<<'\n';
    outfile.close();  //關閉檔案。用完了必須關閉,否則會丟失資料
}

    /*
    *函式名稱:sort_allgrade
    *功能描述:將各位選手的個人得分降序排列,方便看出利用最值進行下一步計算
    *輸入引數:rater_number-評委人數,competitor_number-選手人數
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:這個功能作用不是很大,主要是為了進行去掉最值的計算而設定的
    */
void Competitor::sort_allgrade(int rater_number,int competitor_number,Competitor &competitor)
{
    sort(competitor.grade,competitor.grade+rater_number*competitor_number,compare);//呼叫系統中的sort函式進行將降序排列,方便去掉最值
}

    /*
    *函式名稱:calculate_mark
    *功能描述:計算刪除掉給定數目的最值後選手的平均得分
    *輸入引數:min-評分範圍最小值,max-評分範圍最大值,delete_number-要刪除掉的最值數目
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:無
    */
void Competitor::calculate_mark(int rater_number,int competitor_number,Competitor &competitor,int delete_number)
{
    double sum;
    int i,j;
    for(i=0; i<competitor_number; ++i)
    {
        sum=0;
        for(j=delete_number; j<rater_number-delete_number; ++j)
        {
            sum+=competitor.grade[j];
        }
    }
    competitor.ave=sum/(rater_number-delete_number);//計算選手平均分
    cout<<"選手"<<competitor.no<<",平均分是:"<<(sum/(rater_number-delete_number))<<"分"<<endl;
}

   /*
   *函式名稱:renew
   *功能描述:修改選手得分
   *輸入引數:change_rater-要修改分數所屬的的評委編號,change_score-更新後的分數
   *輸出引數:competitor-類Competitor的物件
   *返回值:無
   *其他說明:無
   */
void Competitor::renew(Competitor &competitor,int change_rater,double change_score)
{
    double *p;//利用指標取地址對相應給定位置的分數進行修改
    p=&competitor.grade[change_rater];
    *p=change_score;
}

   /*
    *函式名稱:writedata
    *功能描述:將修改後的選手得分寫入檔案中
    *輸入引數:rater_number-評委人數
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:寫入一個新的檔案,而不是覆蓋原有的記錄各選手分數的檔案
    */
void Competitor::writedata(int rater_number,Competitor &competitor)
{
    int i;
    ofstream file("summary.txt",ios::app);
    if(!file)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                 //開啟不成功,則提示後退出。
    }
    file<<"選手"<<competitor.no<<":"<<'\t';
    for(i=0; i<rater_number; ++i)
        file<<competitor.grade[i]<<'\t';
    file<<'\n';
    file.close();//關閉檔案
}

    /*
    *函式名稱:storage
    *功能描述:用(二進位制)檔案讀取將各位選手得分、名次和平均分儲存到檔案中
    *輸入引數:rater_number-評委人數,competitor_number-選手人數
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:用兩種方式寫入,ASCII和二進位制
    */
void Competitor::storage(int rater_number,int competitor_number,Competitor &competitor)
{
    int i;
    ofstream file("store.txt",ios::app);//開啟分數檔案
    if(!file)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                //開啟不成功,則提示後退出。
    }
    file<<"選手"<<competitor.no<<":"<<'\t';
    for(i=0; i<rater_number; ++i)
        file<<competitor.grade[i]<<'\t';
    file<<"平均分:"<<competitor.ave;
    file<<'\t';
    file<<"排名:"<<competitor.rank;
    file<<'\n';
    file.close();//關閉檔案
    //以下為二進位制檔案寫入選手排名及其平均得分
    ofstream bfile("binary_store.dat",ios::app|ios::binary);
    if(!bfile)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                //開啟不成功,則提示後退出。
    }
    bfile<<"選手"<<competitor.no<<":"<<'\t';
    bfile.write((char*)&competitor.no, sizeof(int));
    bfile<<":"<<'\t';
    for(i=0; i<rater_number; ++i)
    {
        bfile.write((char*)&competitor.grade[i], sizeof(double));
        bfile<<'\t';
    }
    bfile<<'\n';
    bfile<<"平均分:";
    bfile.write((char*)&competitor.ave, sizeof(double));
    bfile<<'\t';
    bfile<<"排名:";
    bfile.write((char*)&competitor.rank, sizeof(int));
    bfile<<'\n';
    bfile.close();//關閉檔案
}

    /*
    *函式名稱:output_mark
    *功能描述:在螢幕上顯示出選手得分
    *輸入引數:rater_number-評委人數,competitor_number-選手人數
    *輸出引數:competitor-類Competitor的物件
    *返回值:無
    *其他說明:無
    */
void Competitor::output_mark(int rater_number,int n,Competitor &competitor)
{
    int i;
    for(i=0; i<rater_number; ++i)
        cout<<competitor.grade[i]<<'\t';
    cout<<endl;
}






——————類實現——system.cpp


#include <iostream>
#include <fstream>
#include <cstdlib>
#include "system.h"
#include <algorithm>
using namespace std;

    /*
    *函式名稱:initialize_work
    *功能描述:函式初始化的選擇功能選單
    *輸入引數:無
    *輸出引數:無
    *返回值:無
    *其他說明:無
    */
void System::initialize_work()
{
    cout<<"程式初始化中..."<<endl;//以下先給各引數賦值
    cout<<"給引數初始化的方式..."<<endl;
    cout<<"1.從檔案讀取"<<endl;
    cout<<"2.手動輸入"<<endl;
    cout<<"請選擇:";
}

   /*
   *函式名稱:funtion_work
   *功能描述:大獎賽計分系統的選擇功能選單
   *輸入引數:無
   *輸出引數:無
   *返回值:無
   *其他說明:無
   */
void System::funtion_work()
{
    cout<<"                                ———————————"<<endl;
    cout<<"                                歡迎使用大獎賽計分系統"<<endl;
    cout<<"                                ———————————"<<endl;
    cout<<"                                | "<<"1.輸入選手的成績  "<<" |"<<endl;
    cout<<"                                | "<<"2.所有選手的成績  "<<" |"<<endl;
    cout<<"                                | "<<"3.選手成績降序排列"<<" |"<<endl;
    cout<<"                                | "<<"4.選手的最終排名  "<<" |"<<endl;
    cout<<"                                | "<<"5.選手的成績修改  "<<" |"<<endl;
    cout<<"                                | "<<"6.選手的成績儲存  "<<" |"<<endl;
    cout<<"                                | "<<"0.退出            "<<" |"<<endl;
    cout<<"                                ———————————"<<endl;
    cout<<"請選擇:";
}

    /*
    *函式名稱:sort_ave
    *功能描述:依據各位選手的個人平均分降序排列得出選手名次
    *輸入引數:rater_number-評委人數,competitor_number-選手人數
    *輸出引數:s[][2]-只存有選手編號及其平均分
    *返回值:無
    *其他說明:無
    */
void System::sort_ave(int rater_number,int competitor_number,double f[][2])
{
    int i,j,k;
    double t;
    for(j=0; j<=rater_number-1; j++)//根據選手平均分氣泡排序算出排名
        for(i=0; i<rater_number-j-1; i++)
            if (f[i][1]<f[i+1][1])
            {
                t=f[i][1];
                f[i][1]=f[i+1][1];
                f[i+1][1]=t;
                k=f[i][0];
                f[i][0]=f[i+1][0];
                f[i+1][0]=k;
            }
    for(i=0; i<competitor_number; ++i)
    {
        cout<<"第"<<i<<"名:"<<"選手"<<f[i][0]<<endl;
    }
}

    /*
    *函式名稱:file_read
    *功能描述:從相關資料夾中讀取資料進行引數的初始化
    *輸入引數:無
    *輸出引數:rater_number-評委的人數,competitor_number-選手的人數,delete_number-要去掉的最值數目
    min-計分範圍的最小值,max-計分範圍的最大值
    *返回值:無
    *其他說明:無
    */
void System::file_read(int *rater_number,int *competitor_number,int *min,int *max,int *delete_number)
{
    int i;
    int *parameter=new int[5];//parameter陣列用來儲存各項引數
    ifstream infile("mns_read.txt",ios::in); //測試是否成功開啟,開啟失敗時(如要讀的資料檔案不存在)退出
    if(!infile)
    {
        cerr<<"open error!"<<endl;
        abort();
    }
    for(i=0; i<5; ++i)
        infile>>parameter[i];//從檔案中讀取引數
    infile.close(); //讀入完畢一定要關閉檔案
    //用讀取到的引數分別給各項數值賦值
    *rater_number=parameter[0];
    *competitor_number=parameter[1];
    *min=parameter[2];
    *max=parameter[3];
    *delete_number=parameter[4];
    cout<<"評委的人數:"<<*rater_number<<endl;//將檔案中讀取到的各項有關引數顯示在螢幕上
    cout<<"選手的人數:"<<*competitor_number<<endl;
    cout<<"打分範圍:"<<*min<<"-"<<*max<<endl;
    cout<<"要去掉的最值數目:"<<*delete_number<<endl;
    delete [] parameter;
}

    /*
    *函式名稱:file_write
    *功能描述:輸入相關資料完成對各引數的初始化
    *輸入引數:rater_number-評委的人數,competitor_number-選手的人數,delete_number-要去掉的最值數目
    min-計分範圍的最小值,max-計分範圍的最大值
    *輸出引數:rater_number-評委的人數,competitor_number-選手的人數,delete_number-要去掉的最值數目
    min-計分範圍的最小值,max-計分範圍的最大值
    *返回值:無
    *其他說明:各資料會以檔案形式儲存到相關資料夾中
    */
void System::file_write(int *rater_number,int *competitor_number,int *min,int *max,int *delete_number)
{
    int *parameter=new int[5];//parameter陣列用來儲存各項引數
    cout<<"請輸入:"<<endl;//手動輸入各項引數來初始化
    cout<<"評委的人數:";
    cin>>parameter[0];
    cout<<"選手的人數:";
    cin>>parameter[1];
    cout<<"打分範圍(min-max):";
    cin>>parameter[2];
    cin>>parameter[3];
    cout<<"要去掉的最值數目:";
    cin>>parameter[4];
    *rater_number=parameter[0];
    *competitor_number=parameter[1];
    *min=parameter[2];
    *max=parameter[3];
    *delete_number=parameter[4];
    ofstream file("mns_write.txt",ios::out);  //寫入檔案
    if(!file)                    //測試檔案開啟操作是否成功
    {
        cerr<<"open error!"<<endl;
        exit(1);                //開啟不成功,則提示後退出。
    }
    file<<"評委的人數:";
    file<<rater_number<<'\n';
    file<<"選手的人數:";
    file<<competitor_number<<'\n';
    file<<"打分範圍:";
    file<<min<<"-"<<max<<'\n';
    file<<"要去掉的最值數目:";
    file<<delete_number<<'\n';
    file.close();
    delete [] parameter;
}

   /*
   *函式名稱:renew_grade
   *功能描述:修正選手的分數
   *輸入引數:change_competitor-選手的編號,change_rater-評委的編號,change_score-修正後的分數
   min-計分範圍的最小值,max-計分範圍的最大值
   *輸出引數:change_score
   *返回值:無
   *其他說明:無
   */
void System::renew_grade(int *change_competitor,int *change_rater,double *change_score,int min,int max)
{
    int cc,cr;
    double cs;
    cout<<"請輸入要修改的選手編號:";
    cin>>cc;
    *change_competitor=cc;
    cout<<"請輸入評委編號:";
    cin>>cr;
    *change_rater=cr;
    cout<<"請輸入要修改後的成績:";
    cin>>cs;
    while(cs<min||cs>max)
    {
        cerr<<"分數不在正確的範圍內!"<<endl;
        cerr<<"請檢查並請重新輸入該選手的成績:";
        cin>>cs;
    }
    *change_score=cs;
}








編譯通過:




執行結果:


——————檔案讀取初始化引數——








檔案存取:




各檔案:





——————手工輸入初始化引數——













實訓報告:














——————————THE END——————————


相關文章