//---------------------------------------------------------------//

//      <RDB&外部キーの実験>            外部キーの練習.cpp   //

//       "成績処理プログラム"                                    //

//---------------------------------------------------------------//

 

#include<stdio.h>

#include<string.h>

 

///////////////////////成績クラスの定義////////////////////////////

 

class Seiseki{

 

    int no;//出席番号

    int ko,sy,su,ri,ei;//教科の成績

    float av;//全成績の平均

    int ju;//順位

 

    public:

 

    void input(int n,int a,int b,int c,int d,int e){

        no=n; ko=a; sy=b; su=c; ri=d; ei=e; ju=0;

        av = float(a+b+c+d+e)/5;     // 5=科目数

        }

    int   no_output() {return(no);}

    float average_output() {return(av);}

    void  junni_input(int x){ju = x;}

    void  Hyouji(FILE* dat){

        fprintf(dat,"%3d, %3d, %3d, %3d, %3d, (%6.2f) %3d",

        ko,sy,su,ri,ei,av,ju);

    }

};

 

///////////////////////生徒クラスの定義////////////////////////////

 

class Seito{

 

    int no;//出席番号

    char nam[10];//名字

    char nic[10];//名前

    char sin[20];//進路希望

  

    public:

 

    void input(int x,char* y,char* z,char* u){

        no=x;

        strcpy(nam,y);

        strcpy(nic,z);

        strcpy(sin,u);

    }

 

    int no_output(){

        return(no);

    }

 

    void Hyouji(FILE* dat){

        fprintf(dat,"\n\n%3d :%-6s %-6s  [%-8s] : ",no,nam,nic,sin);

    }

};

 

/////////////////////// MAIN 関数の定義////////////////////////////

 

void main(){

 

    Seito   stu[200];//生徒クラスのインスタンス

    Seiseki ten[200];//成績クラスのインスタンス

    int     m,n;

    FILE*   dat;

 

    int stu_yomikomi(FILE*,Seito*);//生徒.dat読み込み関数

    int ten_yomikomi(FILE*,Seiseki*);//成績.dat読み込み関数

    int kakikomi(FILE*,Seito*,Seiseki*,int,int);//成績表.dat書込み関数

 

    // ++++++++生徒データの読み込み++++++++

 

    if((dat = fopen("生徒.dat","r")) != NULL){

        n = stu_yomikomi(dat,stu);

        fclose(dat);

    }

    else{

        printf("\n\n>>>データファイル[成績.dat]が見つかりません。\n");

    }

 

    // ++++++++成績データの読み込み++++++++

 

    if((dat = fopen("成績.dat","r")) != NULL){

        m = ten_yomikomi(dat,ten);

        fclose(dat);

    }

    else{

        printf("\n\n>>>データファイル[生徒.dat]が見つかりません。\n");

 

        //  ++++++++成績表の作成++++++++ 

 

        if(n==0||m==0){

            printf("\n>>> 出力に必要なデータがそろっていません。\n");

        }

        else{

            dat = fopen("成績表.dat","w");

            if(kakikomi(dat,stu,ten,m,n)==1){

                printf("\n\n>>> 処理は終了しました。\n\n");

                fclose(dat);

            }

        }

    }

}

 

//////////////////生徒.dat読み込み関数の定義///////////////////////

 

int stu_yomikomi(FILE* dat,Seito* pstu){

 

    int    xx,k=0;

    int    check;

    char   yy[10],zz[10],uu[20];

 

    while(fscanf(dat,"%d",&xx)!=EOF){

        fscanf(dat,"%s %s %s %d",yy,zz,uu,&check);

        if(check==999){

             (pstu+k)->input(xx,yy,zz,uu);

             k++;

        }

        else{

            printf("\n\n>>>   %d番目の生徒レコードが正しくないので、途中で",k+1);

            break;

        }

    }

    printf("\n>>> 生徒データの入力を終了しました。\n");

    printf(">>> (レコード数:%d)\n",k);

    return(k);

}

 

//////////////////成績.dat読み込み関数の定義///////////////////////

 

int ten_yomikomi(FILE* dat,Seiseki* pten){

 

    int  n,a,b,c,d,e,k=0;

    int  check;

 

    while(fscanf(dat,"%d",&n)!=EOF){

        fscanf(dat,"%d %d %d %d %d %d",&a,&b,&c,&d,&e,&check);

        if(check==999){

            (pten+k)->input(n,a,b,c,d,e);

            k++;

        }

        else{

            printf("\n>>>   %d番目の成績レコードが正しくないので、途中で",k+1);

            break;

        }

        printf(">>> (レコード数:%d)\n",k);

        return(k);

  }

}

 

//////////////////成績表.dat書込み関数の定義///////////////////////

 

int kakikomi(FILE* dat,Seito* pstu,Seiseki* pten,int m,int n){

 

    int l;

    void junnizuke(Seiseki*,int);//成績の順位付け関数

    junnizuke(pten,m);

    fprintf(dat,"-------------成績表-------------\n\n");

    fprintf(dat,"  生徒番号・氏名      進路希望     ");

    fprintf(dat,"国               (平均)  順位");

    for(int j=0;j<n;j++){                     // -------------------------

        for(int i=0;i<m;i++){                 //   生徒データの出席番号を

                                              // 外部キーとして、成績デー

            l = ((pstu+j)->no_output());      // タの主キーと等しいレコー

            if(((pten+i)->no_output()) ==l){  // ドを結合し、その両データ

                                              // の「結合データ」を生徒デ

            (pstu+j)->Hyouji(dat);            // ータのレコード順に表示す

            (pten+i)->Hyouji(dat);            // る。

            break;                            //

        }                                     //

    }                                         //-------------------------

    return(1);

}

 

///////////////////成績の順位付け関数の定義////////////////////////

 

void junnizuke(Seiseki* pten,int m){

 

    int   i,j,k;

    float a[200],aa;

    int   b[200],bb,c[200],cc;

 

    for(k=0;k<m;k++){

        a[k] = (pten+k)->average_output();

        b[k] = k;

    }

    for(i=0;i<m-1;i++){

        for(j=0;j<m-i-1;j++){

            if( a[j] < a[j+1] ){

                aa=a[j];

                bb=b[j];

                a[j]=a[j+1];

                b[j]=b[j+1];

                a[j+1]=aa;

                b[j+1]=bb;

            }

        }

    }

    int l=0;

    for(c[0]=1,k=1;k<m;k++){

        if(a[k-1]==a[k]){

            l++;

        }

        else{

            l=0;

        }

        c[k]=k-l+1;

    }

    for(i=0;i<m-1;i++){

        for(j=0;j<m-i-1;j++){

            if(b[j]>b[j+1]){

                bb=b[j];

                cc=c[j];

                b[j]=b[j+1];

                c[j]=c[j+1];

                b[j+1]=bb;

                c[j+1]=cc;

            }

        }

    }

    for(k=0;k<m;k++){

        (pten+k)->junni_input(c[k]);

    }

}