• 数据结构实训——运动会分数统计


    题目1: 运动会分数统计(限1 人完成)

    任务:

    参加运动会有n个学校,学校编号为1……n。比赛分成m个男子项目,和w个女子项目。项目编号为男子1……m,女子m+1……m+w。不同的项目取前五名或前三名积分;取前五名的积分分别为:7、5、3、2、1,前三名的积分分别为:5、3、2;哪些取前五名或前三名由学生自己设定。(m<=20,n<=20)

    功能要求:

    1. 输入各个项目的前三名或前五名的成绩;
    2. 统计各学校总分;
    3. 按学校编号或名称、学校总分、男女团体总分排序输出;
    4. 按学校编号查询学校某个项目的情况;可以按项目编号查询取得前三或前五名的学校。
    5. 数据存入文件并能随时查询
    6. 规定:输入数据形式和范围:可以输入学校的名称,运动项目的名称

    输出形式:

    有合理的提示,各学校分数为整形

    界面要求:

    有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。

    存储结构:

    学生自己根据系统功能要求自己设计,但是要求运动会的相关数据要存储在数据文件中。(数据文件的数据读写方法等相关内容在c语言程序设计的书上,请自学解决)请在最后的上交资料中指明你用到的存储结构;

    测试数据:

    要求使用1、全部合法数据;2、整体非法数据;3、局部非法数据。进行程序测试,以保证程序的稳定。测试数据及测试结果请在上交的资料中写明;

    附上代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #define SPOMAN_MAX 21   //男子体育项目最大值
    #define SPOWOMAN_MAX 21 //女子体育项目最大值
    #define SCHOOL_MAX 300  //学校个数最大值
    
    struct Sports
    {
        int id;        //体育编号
        char name[20]; //体育名称
        int score;     //体育分数
        int ranking;   //在该体育的排名
    };
    
    struct SCHOOL
    {
        int id;                               //学校编号
        char name[20];                        //学校名字
        int schoolscore;                      //学校总分
        int spomanscore;                      //学校男子项目总分
        int spowomanscore;                    //学校女子项目总分
        struct Sports spoman[SPOMAN_MAX];     //男子项目数组
        struct Sports spowoman[SPOWOMAN_MAX]; //女子项目数组
        struct SCHOOL *next;                  //指向下一个学校
    };
    
    int SPORTMAN, SPORTWOMAN;                 //全局变量:存储数据文件的男女项目个数
    int SCHOOLNUMS;                           //学校个数
    int sportflag[SPOMAN_MAX + SPOWOMAN_MAX]; //存放倒数第一行前三或前五标记
    
    void sortsportid(struct SCHOOL *head, int *spflag, int *flag, int AscDesc, int *output);
    
    void Writecsv()
    { //手动输入数据文件
        FILE *fp;
        int n, i, j, m, w, temp, scanfflag;
        char schname[33], soprname[20], tip[300] = "输入学校名称";
        srand(time(NULL));
    
        fp = fopen("学校体育项目.csv", "w");
        if (fp == NULL)
        {
            printf("学校体育项目.csv文件创建失败
    ");
            system("pause");
            exit(1);
        }
    
        fprintf(fp, "学校编号,学校名字");
        printf("输入男子项目m,女子项目w(例如2,3)
    ");
        printf("0<=m<=%d,0<=w<=%d : ", SPOMAN_MAX, SPOWOMAN_MAX);
        scanfflag = scanf("%d,%d", &m, &w);
        while (scanfflag != 2 || m < 0 || m > SPOMAN_MAX || w < 0 || w > SPOWOMAN_MAX)
        {
            fflush(stdin);
            printf("输入不规范或w或m不在范围
    请重新输入男子项目m,女子项目w:
    ");
            scanfflag = scanf("%d,%d", &m, &w);
        }
    
        if (m)
            printf("输入%d个男子项目名称:
    ", m);
        for (i = 1; i <= m; i++)
        {
            scanf("%s", &soprname);
            printf("男子项目%d写入成功
    ", i);
            strcat(tip, " ");
            strcat(tip, soprname);
            fprintf(fp, ",%s", soprname);
        }
    
        if (w)
            printf("输入%d个女子项目名称:
    ", w);
        for (i = 1; i <= w; i++)
        {
            scanf("%s", &soprname);
            printf("女子项目%d写入成功
    ", i);
            strcat(tip, " ");
            strcat(tip, soprname);
            fprintf(fp, ",%s", soprname);
        }
        fputc('
    ', fp);
        printf("输入参加运动会学校个数n:
    ");
        printf("n的范围为1<= n <=%d
    ", SCHOOL_MAX);
        scanfflag = scanf("%d", &n);
        while (scanfflag != 1 || n <= 0 || n > SCHOOL_MAX)
        {
            fflush(stdin);
            printf("输入不规范或n不在范围
    请重新输入参加运动会学校个数n:
    ");
            scanfflag = scanf("%d", &n);
        }
    
        printf("%s", tip);
        printf("体育项目分数");
        printf("
    例如:XXXX大学 体育A分数 体育B分数 体育C分数 体育D分数 体育E分数
    ");
        for (i = 1; i <= n; i++)
        {
            scanf("%s", &schname);
            fprintf(fp, "%d,%s", i, schname);
            for (j = 1; j <= m + w; j++)
            {
                scanf("%d", &temp);
                fprintf(fp, ",%d", temp);
            }
            fputc('
    ', fp);
            printf("学校%d数据写入成功
    ", i);
        }
    
        fprintf(fp, "1,1");     //前面两位为:1,1即为体育项目性别编号,后面0表示男,1表示女
        for (j = 0; j < m; j++) //输出男子项目标记
            fprintf(fp, ",%d", 0);
        for (j; j < m + w; j++) //输出女子项目标记
            fprintf(fp, ",%d", 1);
        fputc('
    ', fp);
    
        fprintf(fp, "0,0");         //前面两位为:0,0即为体育项目取前三or前五名编号,后面0表示取前三,1表示取前五
        for (j = 0; j < m + w; j++) //输出取前三或者前五标记
            fprintf(fp, ",%d", rand() % 2);
    
        fclose(fp); /*关闭文件*/
        printf("数据文件"学校体育项目.csv"生成成功!
    ");
        printf(""学校体育项目.csv"文件位于: ");
        system("echo %cd%");
        fflush(stdin);
        printf("是否打开"学校体育项目.csv"查看?(y/n)
    查看完记得关闭文件哦
    ");
        if ('y' == getchar())
            system("学校体育项目.csv");
    }
    
    void Randwritecsv()
    { //随机生成数据文件函数
        int schid, sporid, i, j, k, scanfflag;
        int n, m, w, sch[SCHOOL_MAX], spo[SPOMAN_MAX], flag, score;
        FILE *scfp, *spfp, *fp;
        char schname[17], sporname[12];
    
        scfp = fopen("schoolname.csv", "r");
        spfp = fopen("sports.csv", "r");
        fp = fopen("学校体育项目.csv", "w");
    
        if (scfp == NULL)
        {
            printf("schoolname.csv读取失败
    ");
            system("pause");
            exit(1);
        }
        if (spfp == NULL)
        {
            printf("sports.csv读取失败
    ");
            system("pause");
            exit(1);
        }
        if (fp == NULL)
        {
            printf("学校体育项目.csv文件创建失败
    ");
            system("pause");
            exit(1);
        }
    
        srand(time(NULL));
    
        printf("是否随机生成学校个数,男女体育项目个数?
    输入非0表示随机生成,输入0表示手动输入:
    ");
        scanfflag = scanf("%d", &flag);
        while (scanfflag != 1)
        {
            fflush(stdin);
            printf("输入不规范,请重新输入!
    ");
            scanfflag = scanf("%d", &flag);
        }
    
        if (flag == 0)
        {
            printf("请输入学校个数n(1<=n<=%d):", SCHOOL_MAX);
            scanfflag = scanf("%d", &n);
            while (scanfflag != 1 || n > SCHOOL_MAX || n < 1)
            {
                fflush(stdin);
                printf("请重新输入学校个数n(1<=n<=%d):", SCHOOL_MAX);
                scanfflag = scanf("%d", &n);
            }
    
            printf("请输入男子体育项目个数m(0<=m<=%d):", SPOMAN_MAX);
            scanfflag = scanf("%d", &m);
            while (scanfflag != 1 || m > SPOMAN_MAX || m < 0)
            {
                fflush(stdin);
                printf("请重新输入男子体育项目个数m(0<=m<=%d):", SPOMAN_MAX);
                scanfflag = scanf("%d", &m);
            }
    
            printf("请输入女子体育项目个数w(0<=w<=%d):", SPOWOMAN_MAX);
            scanfflag = scanf("%d", &w);
            while (scanfflag != 1 || w > SPOWOMAN_MAX || w < 0)
            {
                fflush(stdin);
                printf("请重新输入男子体育项目个数w(0<=w<=%d):", SPOWOMAN_MAX);
                scanfflag = scanf("%d", &w);
            }
        }
        else
        {
            n = rand() % SCHOOL_MAX + 1;     //n范围 1-SCHOOL_MAX
            m = rand() % (SPOMAN_MAX + 1);   //m范围 0-SPOMAN_MAX
            w = rand() % (SPOWOMAN_MAX + 1); //w范围 0-SPOMAN_MAX
        }
    
        fprintf(fp, "学校编号,学校名字");
    
        for (j = 0; j < m; j++) //随机生成男子项目
        {
            sporid = rand() % 21; //随机生成男子体育项目
            while (1)
            {
                flag = 1; //标记
                for (k = 0; k < j; k++)
                    if (spo[k] == sporid) //判断已有男子体育名字与新的有无重复
                    {
                        flag = 0; //重复则修改标记
                        break;
                    }
                if (flag == 0)
                    sporid = rand() % 21; //重复就重新随机生成
                else
                {
                    spo[j] = sporid; //没有重复就加入数组
                    break;
                }
            }
            fseek(spfp, sporid * 13, SEEK_SET);
            fscanf(spfp, "%s", &sporname);
            fprintf(fp, ",%s", sporname);
        }
        for (j = 0; j < w; j++) //随机生成女子项目
        {
            sporid = rand() % 21;
            while (1)
            {
                flag = 1; //标记
                for (k = 0; k < j; k++)
                    if (spo[k] == sporid) //判断已有男子体育名字与新的有无重复
                    {
                        flag = 0; //重复则修改标记
                        break;
                    }
                if (flag == 0)
                    sporid = rand() % 21; //重复就重新随机生成
                else
                {
                    spo[j] = sporid; //没有重复就加入数组
                    break;
                }
            }
    
            fseek(spfp, sporid * 13, SEEK_SET);
            fscanf(spfp, "%s", &sporname);
            fprintf(fp, ",%s", sporname);
        }
        fputc('
    ', fp);
        for (i = 0; i < n; i++)
        {
            schid = rand() % 300; //随机生成学校名字
            while (1)
            {
                flag = 1; //标记
                for (j = 0; j < i; j++)
                    if (sch[j] == schid) //判断已有学校名字与新的有无重复
                    {
                        flag = 0; //重复则修改标记
                        break;
                    }
                if (flag == 0)
                    schid = rand() % 300; //重复就重新随机生成
                else
                {
                    sch[i] = schid; //没有重复就加入数组
                    break;
                }
            }
            fseek(scfp, schid * 19, SEEK_SET);
            fscanf(scfp, "%s", &schname);
            fprintf(fp, "%d,%s", i, schname);
            for (j = 0; j < m + w; j++)
            {
                score = rand() % 101; //随机生成体育项目分数,范围0-100
                fprintf(fp, ",%d", score);
            }
            fputc('
    ', fp);
        }
        fprintf(fp, "1,1");     //前面两位为:1,1即为体育项目性别编号,后面0表示男,1表示女
        for (j = 0; j < m; j++) //输出男子项目标记
            fprintf(fp, ",%d", 0);
        for (j = 0; j < w; j++) //输出女子项目标记
            fprintf(fp, ",%d", 1);
        fputc('
    ', fp);
    
        fprintf(fp, "0,0");         //前面两位为:0,0即为体育项目取前三or前五名编号,后面0表示取前三,1表示取前五
        for (j = 0; j < m + w; j++) //输出取前三或者前五标记
            fprintf(fp, ",%d", rand() % 2);
    
        fclose(spfp);
        fclose(scfp);
        fclose(fp);
        printf("共写入:%d条学校记录,男子项目:%d项,女子项目:%d项
    ", n, m, w);
        printf("数据文件"学校体育项目.csv"生成成功!
    ");
        printf(""学校体育项目.csv"文件位于: ");
        system("echo %cd%");
        fflush(stdin);
        printf("是否打开"学校体育项目.csv"查看?(y/n)");
        if ('y' == getchar())
            system("学校体育项目.csv");
    }
    
    void ReadFile(struct SCHOOL *head)
    { //读取文件函数
        char *str1, *str2, *str;
        char sportname[SPOMAN_MAX + SPOWOMAN_MAX][12]; //存放第一行男子项目,女子项目名字
        int i, j;
        int hangnum[SCHOOL_MAX + 3] = {0}; //存数据文件每一行的开头到文件头位置
        int hangsum;                       //存放行数0-n
        char A;
        char hang[700]; //存放每行数据
        struct SCHOOL *p = head, *q;
    
        FILE *fp;
        fp = fopen("学校体育项目.csv", "r");
        while (fp == NULL)
        {
            printf("数据文件"学校体育项目.csv"未能找到!
    ");
            printf("是否重新打开?(y/n):");
            fflush(stdin);
            if (getchar() == 'y')
                fp = fopen("学校体育项目.csv", "r");
            else
            {
                printf("文件"学校体育项目.csv"未能打开!
    退出程序
    ");
                system("pause");
                exit(1);
            }
        }
        i = 1;
        while (feof(fp) == 0)
        {
            A = fgetc(fp);
            if (A == '
    ')
            {
                hangnum[i] = (int)ftell(fp);
                i++;
            }
        }
        hangnum[i] = (int)ftell(fp);
        hangsum = i;
    
        rewind(fp); //重新回到文件头
    
        SPORTMAN = SPORTWOMAN = 0; //男女子体育项目个数清零
        SCHOOLNUMS = 0;            //学校个数清零
    
        fseek(fp, hangnum[hangsum - 2], SEEK_SET);
        fgets(hang, hangnum[hangsum - 1] - hangnum[hangsum - 2] - 1, fp);
        str1 = strtok(hang, ",");
        str2 = strtok(NULL, ",");
        if (strcmp(str1, "1") == 0 && strcmp(str2, "1") == 0)
        { //读取倒数第二行的男女体育项目个数信息
            while (1)
            {
                str = strtok(NULL, ",");
                if (str == NULL)
                    break;
                if (strcmp(str, "0") == 0)
                    SPORTMAN++;
                else if (strcmp(str, "1") == 0)
                    SPORTWOMAN++;
            }
        }
        fseek(fp, hangnum[hangsum - 1], SEEK_SET);
        fgets(hang, hangnum[hangsum] - hangnum[hangsum - 1] + 1, fp);
        str1 = strtok(hang, ",");
        str2 = strtok(NULL, ",");
        if (strcmp(str1, "0") == 0 && strcmp(str2, "0") == 0)
        { //读取倒数第一行的取前三还是前五信息
            j = 0;
            while (1)
            {
                str = strtok(NULL, ",");
                if (str == NULL)
                    break;
                if (strcmp(str, "0") == 0 || strcmp(str, "1") == 0)
                    sportflag[j++] = atoi(str);
            }
        }
    
        for (i = 0; i < hangsum - 2; i++)
        {
            fseek(fp, hangnum[i], SEEK_SET);
            fgets(hang, hangnum[i + 1] - hangnum[i] - 1, fp);
            str1 = strtok(hang, ",");
            str2 = strtok(NULL, ",");
            if (strcmp(str1, "学校编号") == 0 && strcmp(str2, "学校名字") == 0)
            {
                j = 0;
                while (1)
                {
                    str = strtok(NULL, ",");
                    if (str == NULL)
                        break;
                    strcpy(sportname[j++], str); //读取文件头一行的体育名字
                }
            }
            else
            {
                SCHOOLNUMS++;
                q = (struct SCHOOL *)malloc(sizeof(struct SCHOOL));
                q->next = NULL;
                q->id = atoi(str1);
                strcpy(q->name, str2);
                q->schoolscore = 0;
                q->spomanscore = 0;
                q->spowomanscore = 0;
                j = 0;
                while (1)
                {
                    str = strtok(NULL, ",");
                    if (str == NULL)
                        break;
                    if (j < SPORTMAN)
                    {
                        q->spoman[j].id = j;                     //体育项目编号
                        strcpy(q->spoman[j].name, sportname[j]); //体育项目名字
                        q->spoman[j].score = atoi(str);          //体育项目分数
                    }
                    if (j >= SPORTMAN && j < SPORTMAN + SPORTWOMAN)
                    {
                        q->spowoman[j - SPORTMAN].id = j;                     //体育项目编号
                        strcpy(q->spowoman[j - SPORTMAN].name, sportname[j]); //体育项目名字
                        q->spowoman[j - SPORTMAN].score = atoi(str);          //体育项目分数
                    }
                    j++;
                }
                p->next = q;
                p = q;
            }
        }
        fclose(fp);
    }
    
    void put_over_data(struct SCHOOL *head)
    { //显示从文件读取的信息
        struct SCHOOL *p = head, *q;
        int i, j;
        char text1[] = "学校编号", text2[] = "学校名字";
        ReadFile(head); //调用读文件函数
        q = p->next;
        printf("%-10s%-16s", text1, text2);
        for (i = 0; i < SPORTMAN; i++)
            printf("%s%s:%d%4s", q->spoman[i].name, "男", q->spoman[i].id, "");
        for (i = 0; i < SPORTWOMAN; i++)
            printf("%s%s:%d%4s", q->spowoman[i].name, "女", q->spowoman[i].id, "");
        printf("
    ");
    
        p = head;
        for (i = 0; i < SCHOOLNUMS; i++)
        {
            q = p->next;
            printf("%-10d%-16s", q->id, q->name);
            for (j = 0; j < SPORTMAN; j++)
                printf("%10d%4s", q->spoman[j].score, "");
            for (j = 0; j < SPORTWOMAN; j++)
                printf("%10d%4s", q->spowoman[j].score, "");
            printf("
    ");
            p = q;
        }
    }
    
    void put_over_data_score(struct SCHOOL *head)
    { //显示全部信息,总分,男女总分
        struct SCHOOL *p = head, *q;
        int i, j;
        char text1[] = "学校编号", text2[] = "学校名字", text3[] = "学校总分", text4[] = "男子总分", text5[] = "女子总分";
        q = p->next;
        printf("%-10s%-16s", text1, text2);
        for (i = 0; i < SPORTMAN; i++)
            printf("%s%s:%d%4s", q->spoman[i].name, "男", q->spoman[i].id, "");
        for (i = 0; i < SPORTWOMAN; i++)
            printf("%s%s:%d%4s", q->spowoman[i].name, "女", q->spowoman[i].id, "");
        printf("%-10s%-10s%-10s
    ", text3, text4, text5);
    
        p = head;
        for (i = 0; i < SCHOOLNUMS; i++)
        {
            q = p->next;
            printf("%-10d%-16s ", q->id, q->name);
            for (j = 0; j < SPORTMAN; j++)
                printf("%-14d", q->spoman[j].score);
            for (j = 0; j < SPORTWOMAN; j++)
                printf("%-14d", q->spowoman[j].score);
            printf("%-10d%-10d%-10d
    ", q->schoolscore, q->spomanscore, q->spowomanscore);
            p = q;
        }
    }
    
    void Statotalscore(struct SCHOOL *head)
    { //统计总分函数
        int i, j, k;
        int qian3[3] = {5, 3, 2}, qian5[5] = {7, 5, 3, 2, 1};
        int rank[SCHOOL_MAX];
        struct SCHOOL *p = head, *q;
        struct SCHOOL *temp, *spscqian, *spmaxqian; //spscqian存储交换位置前驱,spmaxqian存储最大的前驱
        ReadFile(head);
        for (i = 0; i < SPORTMAN; i++) //男子体育项目分数计算
        {
            for (j = 1; j < SCHOOLNUMS; j++) //排序学校个数-1趟
            {
                p = head;
                for (k = 0; k < j; k++) //跳过前j个已经排好序的
                {
                    spmaxqian = spscqian = p; //假设最大是第j个,记下第j个交换位置的前驱
                    q = p->next;
                    p = q;
                }
                for (k = j; k < SCHOOLNUMS; k++) //查找比较交换
                {
                    q = p->next;
                    if ((spmaxqian->next)->spoman[i].score < q->spoman[i].score) //读出体育项目分数比较
                        spmaxqian = p;
                    p = q;
                }
                temp = spscqian->next;
                spscqian->next = spmaxqian->next;
                spmaxqian->next = temp;
                temp = spscqian->next->next;
                spscqian->next->next = spmaxqian->next->next;
                spmaxqian->next->next = temp;
            }
            p = head;
            k = 0;
            for (j = 0; j < SCHOOLNUMS; j++)
            {
                q = p->next;
                rank[k] = q->spoman[i].score;
                if (k > 0 && rank[k - 1] == rank[k])
                    k--;
                q->spoman[i].ranking = k + 1; //把排名存进每个体育项目数组中
                if (sportflag[i] == 0)        //取前三名,前三名积分为:5、3、2
                {
                    if (k < 3)
                    {
                        q->schoolscore += qian3[k];
                        q->spomanscore += qian3[k];
                    }
                }
                else if (sportflag[i] == 1) //取前五名,积分分别为:7、5、3、2、1
                {
                    if (k < 5)
                    {
                        q->schoolscore += qian5[k];
                        q->spomanscore += qian5[k];
                    }
                }
                p = q;
                k++;
            }
        }
        for (i = 0; i < SPORTWOMAN; i++) //女子体育项目分数计算
        {
            for (j = 1; j < SCHOOLNUMS; j++) //排序学校个数-1趟
            {
                p = head;
                for (k = 0; k < j; k++) //跳过前j个已经排好序的
                {
                    spmaxqian = spscqian = p; //记下第j个交换位置的前驱,假设第j个为最大
                    q = p->next;
                    p = q;
                }
                for (k = j; k < SCHOOLNUMS; k++) //查找比较交换
                {
                    q = p->next;
                    if ((spmaxqian->next)->spowoman[i].score < q->spowoman[i].score) //读出体育项目分数比较
                        spmaxqian = p;
                    p = q;
                }
                temp = spscqian->next;
                spscqian->next = spmaxqian->next;
                spmaxqian->next = temp;
                temp = spscqian->next->next;
                spscqian->next->next = spmaxqian->next->next;
                spmaxqian->next->next = temp;
            }
            p = head;
            k = 0;
            for (j = 0; j < SCHOOLNUMS; j++)
            {
                q = p->next;
                rank[k] = q->spowoman[i].score;
                if (k > 0 && rank[k - 1] == rank[k])
                    k--;
                q->spowoman[i].ranking = k + 1;   //把排名存进每个体育项目数组中
                if (sportflag[i + SPORTMAN] == 0) //取前三名,前三名积分为:5、3、2
                {
                    if (k < 3)
                    {
                        q->schoolscore += qian3[k];
                        q->spowomanscore += qian3[k];
                    }
                }
                else if (sportflag[i + SPORTMAN] == 1) //取前五名,积分分别为:7、5、3、2、1
                {
                    if (k < 5)
                    {
                        q->schoolscore += qian5[k];
                        q->spowomanscore += qian5[k];
                    }
                }
                p = q;
                k++;
            }
        }
    }
    
    void Sortdata(struct SCHOOL *head, int command, int AscDesc, int *output)
    { //排序:command:1学校编号,2学校名字,3学校总分,4男子总分,5女子总分,AscDesc:0升序,1降序,output 1输出
        int j, k;
        struct SCHOOL *p = head, *q;
        struct SCHOOL *spqian, *spscqian, *temp;
        int sportid, scaflag, spflag, flag;
        system("cls");
        switch (command)
        {
        case 1:                              //按学校编号排序,升序or降序
            for (j = 1; j < SCHOOLNUMS; j++) //排序学校个数-1趟
            {
                p = head;
                for (k = 0; k < j; k++) //跳过前j个已经排好序的
                {
                    spqian = spscqian = p; //假设最大是第j个,记下第j个交换位置的前驱
                    q = p->next;
                    p = q;
                }
                for (k = j; k < SCHOOLNUMS; k++) //查找比较交换
                {
                    q = p->next;
                    if (AscDesc)
                    {
                        if ((spqian->next)->id < q->id) //读出学校编号比较
                            spqian = p;                 //降序
                    }
                    else
                    {
                        if ((spqian->next)->id > q->id) //读出学校编号比较
                            spqian = p;                 //升序
                    }
                    p = q;
                }
                temp = spscqian->next;
                spscqian->next = spqian->next;
                spqian->next = temp;
                temp = spscqian->next->next;
                spscqian->next->next = spqian->next->next;
                spqian->next->next = temp;
            }
            break;
        case 2:                              //按学校名字排序,升序or降序
            for (j = 1; j < SCHOOLNUMS; j++) //排序学校个数-1趟
            {
                p = head;
                for (k = 0; k < j; k++) //跳过前j个已经排好序的
                {
                    spqian = spscqian = p; //假设最大是第j个,记下第j个交换位置的前驱
                    q = p->next;
                    p = q;
                }
                for (k = j; k < SCHOOLNUMS; k++) //查找比较交换
                {
                    q = p->next;
                    if (AscDesc)
                    {
                        if (strcmp((spqian->next)->name, q->name) < 0) //读出学校名字比较
                            spqian = p;                                //降序
                    }
                    else
                    {
                        if (strcmp((spqian->next)->name, q->name) > 0) //读出学校名字比较
                            spqian = p;                                //升序
                    }
                    p = q;
                }
                temp = spscqian->next;
                spscqian->next = spqian->next;
                spqian->next = temp;
                temp = spscqian->next->next;
                spscqian->next->next = spqian->next->next;
                spqian->next->next = temp;
            }
            break;
        case 3:                              //按学校总分排序,升序or降序
            for (j = 1; j < SCHOOLNUMS; j++) //排序学校个数-1趟
            {
                p = head;
                for (k = 0; k < j; k++) //跳过前j个已经排好序的
                {
                    spqian = spscqian = p; //假设最大是第j个,记下第j个交换位置的前驱
                    q = p->next;
                    p = q;
                }
                for (k = j; k < SCHOOLNUMS; k++) //查找比较交换
                {
                    q = p->next;
                    if (AscDesc)
                    {
                        if ((spqian->next)->schoolscore < q->schoolscore) //读出学校总分比较
                            spqian = p;                                   //降序
                    }
                    else
                    {
                        if ((spqian->next)->schoolscore > q->schoolscore) //读出学校总分比较
                            spqian = p;                                   //升序
                    }
                    p = q;
                }
                temp = spscqian->next;
                spscqian->next = spqian->next;
                spqian->next = temp;
                temp = spscqian->next->next;
                spscqian->next->next = spqian->next->next;
                spqian->next->next = temp;
            }
            break;
        case 4:                              //按男子总分排序,升序or降序
            for (j = 1; j < SCHOOLNUMS; j++) //排序学校个数-1趟
            {
                p = head;
                for (k = 0; k < j; k++) //跳过前j个已经排好序的
                {
                    spqian = spscqian = p; //假设最大是第j个,记下第j个交换位置的前驱
                    q = p->next;
                    p = q;
                }
                for (k = j; k < SCHOOLNUMS; k++) //查找比较交换
                {
                    q = p->next;
                    if (AscDesc)
                    {
                        if ((spqian->next)->spomanscore < q->spomanscore) //读出男子总分比较
                            spqian = p;                                   //降序
                    }
                    else
                    {
                        if ((spqian->next)->spomanscore > q->spomanscore) //读出男子总分比较
                            spqian = p;                                   //升序
                    }
                    p = q;
                }
                temp = spscqian->next;
                spscqian->next = spqian->next;
                spqian->next = temp;
                temp = spscqian->next->next;
                spscqian->next->next = spqian->next->next;
                spqian->next->next = temp;
            }
            break;
        case 5:                              //按女子总分排序,升序or降序
            for (j = 1; j < SCHOOLNUMS; j++) //排序学校个数-1趟
            {
                p = head;
                for (k = 0; k < j; k++) //跳过前j个已经排好序的
                {
                    spqian = spscqian = p; //假设最大是第j个,记下第j个交换位置的前驱
                    q = p->next;
                    p = q;
                }
                for (k = j; k < SCHOOLNUMS; k++) //查找比较交换
                {
                    q = p->next;
                    if (AscDesc)
                    {
                        if ((spqian->next)->spowomanscore < q->spowomanscore) //读出女子总分比较
                            spqian = p;                                       //降序
                    }
                    else
                    {
                        if ((spqian->next)->spowomanscore > q->spowomanscore) //读出女子总分比较
                            spqian = p;                                       //升序
                    }
                    p = q;
                }
                temp = spscqian->next;
                spscqian->next = spqian->next;
                spqian->next = temp;
                temp = spscqian->next->next;
                spscqian->next->next = spqian->next->next;
                spqian->next->next = temp;
            }
            break;
        case 6: //按输入体育项目编号排序,升序or降序
            sortsportid(head, &spflag, &flag, AscDesc, output);
            break;
        }
    }
    
    void sortsportid(struct SCHOOL *head, int *spflag, int *flag, int AscDesc, int *output)
    {
        struct SCHOOL *p, *q, *spqian, *spscqian, *temp;
        int scaflag, sportid, j, k;
        p = head->next;
        for (j = 0; j < SPORTMAN; j++) //输出体育男子项目名字
            printf("%s:%d, ", p->spoman[j].name, p->spoman[j].id);
        for (j = 0; j < SPORTWOMAN; j++) //输出体育女子项目名字
            printf("%s:%d, ", p->spowoman[j].name, p->spowoman[j].id);
        printf("
    
    输入体育项目编号以选择排序
    ");
        scaflag = scanf("%d", &sportid);
        while (scaflag != 1)
        {
            fflush(stdin);
            printf("输入的不是数字,请重新输入!
    ");
            scaflag = scanf("%d", &sportid);
        }
        p = head->next; //循环查找符合编号的体育项目
        *flag = 0;
        for (j = 0; j < SPORTMAN; j++)
            if (sportid == p->spoman[j].id)
            {
                *spflag = j;
                *flag = 1;
                break;
            }
        for (j = 0; j < SPORTWOMAN; j++)
            if (sportid == p->spowoman[j].id)
            {
                *spflag = j;
                *flag = 2;
                break;
            }
        if (*flag)
            for (j = 1; j < SCHOOLNUMS; j++) //排序学校个数-1趟
            {
                p = head;
                for (k = 0; k < j; k++) //跳过前j个已经排好序的
                {
                    spqian = spscqian = p; //假设最大是第j个,记下第j个交换位置的前驱
                    q = p->next;
                    p = q;
                }
                for (k = j; k < SCHOOLNUMS; k++) //查找比较交换
                {
                    q = p->next;
                    if (AscDesc)
                    {
                        if (*flag == 1)
                        {
                            if ((spqian->next)->spoman[*spflag].score < q->spoman[*spflag].score) //读出体育项目比较
                                spqian = p;                                                       //降序
                        }
                        else if (*flag == 2)
                        {
                            if ((spqian->next)->spowoman[*spflag].score < q->spowoman[*spflag].score) //读出体育项目比较
                                spqian = p;                                                           //降序
                        }
                    }
                    else
                    {
                        if (*flag == 1)
                        {
                            if ((spqian->next)->spoman[*spflag].score > q->spoman[*spflag].score) //读出体育项目比较
                                spqian = p;                                                       //升序
                        }
                        else if (*flag == 2)
                        {
                            if ((spqian->next)->spowoman[*spflag].score > q->spowoman[*spflag].score) //读出体育项目比较
                                spqian = p;                                                           //升序
                        }
                    }
                    p = q;
                }
                temp = spscqian->next;
                spscqian->next = spqian->next;
                spqian->next = temp;
                temp = spscqian->next->next;
                spscqian->next->next = spqian->next->next;
                spqian->next->next = temp;
            }
        else
        {
            *output = 0;
            printf("查无此项!
    ");
        }
    }
    
    void Mainmenu()
    { //主菜单
        printf("实验一:
    ");
        printf("---------------------------------运动会分数统计---------------------------------
    ");
        printf("--------------------------------------------------------------------------------
    ");
        printf("-------------------------------1.体育成绩文件生成-------------------------------
    ");
        printf("----------------------------2.体育成绩文件读取并显示----------------------------
    ");
        printf("---------------3.按学校编号、名称、学校总分、男女团体总分排序输出---------------
    ");
        printf("-----------------------4.按学校编号查询学校某个项目的情况-----------------------
    ");
        printf("---------------------5.按项目编号查询取得前三或前五名的学校---------------------
    ");
        printf("-----------------------------------6.退出程序-----------------------------------
    ");
        printf("--------------------------------------------------------------------------------
    ");
        printf("--------------------------------------------------------2019年12月21日--XX编写
    ");
    }
    
    void menu1makefile()
    { //菜单1
        int com2, scaflag;
        system("cls");
        printf("------------------------1.手动输入学校名字,体育项目及成绩-----------------------
    ");
        printf("------------------------2.随机生成学校名字,体育项目及成绩-----------------------
    ");
        printf("----------------------------------3.返回上一级?--------------------------------
    ");
        printf("输入一个数选择功能:");
        scaflag = scanf("%d", &com2);
        while (scaflag != 1 || com2 < 1 || com2 > 3)
        {
            fflush(stdin);
            printf("输入的不是数字或输入的数不符合条件,请重新输入!
    ");
            scaflag = scanf("%d", &com2);
        }
        if (com2 == 1)
            Writecsv();
        else if (com2 == 2)
            Randwritecsv();
        if (com2 != 3)
            system("pause");
        system("cls");
    }
    
    void menu3sortput(struct SCHOOL *head)
    { //菜单3
        int com2, scaflag, output;
        Statotalscore(head); //计算总分
        while (1)
        {
            system("cls");
            printf("-------------------------------1.按学校编号降序输出-----------------------------
    ");
            printf("-------------------------------2.按学校编号升序输出-----------------------------
    
    ");
            printf("-------------------------------3.按学校名字降序输出-----------------------------
    ");
            printf("-------------------------------4.按学校名字升序输出-----------------------------
    
    ");
            printf("-------------------------------5.按学校总分降序输出-----------------------------
    ");
            printf("-------------------------------6.按学校总分升序输出-----------------------------
    
    ");
            printf("-------------------------------7.按男子总分降序输出-----------------------------
    ");
            printf("-------------------------------8.按男子总分升序输出-----------------------------
    
    ");
            printf("-------------------------------9.按女子总分降序输出-----------------------------
    ");
            printf("------------------------------10.按女子总分升序输出-----------------------------
    
    ");
            printf("--------------------------11.按输入体育项目编号降序输出-------------------------
    ");
            printf("--------------------------12.按输入体育项目编号升序输出-------------------------
    
    ");
            printf("---------------------------------13.返回上一级?--------------------------------
    ");
            printf("输入一个数选择功能:");
            scaflag = scanf("%d", &com2);
            while (scaflag != 1 || com2 < 1 || com2 > 13)
            {
                fflush(stdin);
                printf("输入的不是数字或输入的数不符合条件,请重新输入!
    ");
                scaflag = scanf("%d", &com2);
            }
            if (com2 == 13)
                break;
            else
            {
                output = 1;
                Sortdata(head, com2 / 2 + com2 % 2, com2 % 2, &output); //按要求排序
                if (output)
                    put_over_data_score(head); //输出排序后结果
            }
            system("pause");
            system("cls");
        }
        system("cls");
    }
    
    void menu4(struct SCHOOL *head)
    { //菜单4
        int i, j;
        struct SCHOOL *p, *q;
        int schid, spoid, schflag = 0, spoflag = 0, scaflag;
        system("cls");
        Statotalscore(head); //计算总分
        printf("学校名字--学校编号
    ");
        p = head;
        for (i = 0; i < SCHOOLNUMS; i++)
        {
            q = p->next;
            printf("%s--%d	", q->name, q->id);
            p = q;
            if (i % 6 == 0)
                printf("
    ");
        }
        p = head->next;
        printf("
    
    体育项目名字--编号
    ");
        for (i = 0; i < SPORTMAN; i++)
            printf("%s(%s)--%d
    ", p->spoman[i].name, "男", p->spoman[i].id);
        for (i = 0; i < SPORTWOMAN; i++)
            printf("%s(%s)--%d
    ", p->spowoman[i].name, "女", p->spowoman[i].id);
        printf("
    输入学校编号,体育项目编号
    例如:1,2
    ");
        scaflag = scanf("%d,%d", &schid, &spoid);
        while (scaflag != 2)
        {
            printf("输入不规范,请重新输入
    ");
            fflush(stdin);
            scaflag = scanf("%d,%d", &schid, &spoid);
        }
        p = head;
        for (i = 0; i < SCHOOLNUMS; i++)
        {
            q = p->next;
            if (q->id == schid)
            {
                schflag = 1;
                break;
            }
            p = q;
        }
        if (schflag)
        {
            for (i = 0; i < SPORTMAN; i++)
                if (spoid == q->spoman[i].id)
                {
                    spoflag = 1;
                    break;
                }
            for (j = 0; j < SPORTWOMAN; j++)
                if (spoid == q->spowoman[j].id)
                {
                    spoflag = 2;
                    break;
                }
            if (spoflag == 1)
                printf("%s的%s(%s)成绩为第%d名
    ", q->name, q->spoman[i].name, "男", q->spoman[i].ranking);
            else if (spoflag == 2)
                printf("%s的%s(%s)成绩为第%d名
    ", q->name, q->spowoman[j].name, "女", q->spowoman[j].ranking);
            else
                printf("%s没有此项体育项目!
    ", q->name);
        }
        else
            printf("查无此校!
    ");
        printf("
    %s全部体育项目情况:
    ", q->name);
        if (schflag && spoflag)
        {
            for (i = 0; i < SPORTMAN; i++)
                printf("%s(%s)第%d名
    ", q->spoman[i].name, "男", q->spoman[i].ranking);
            for (i = 0; i < SPORTWOMAN; i++)
                printf("%s(%s)第%d名
    ", q->spowoman[i].name, "女", q->spowoman[i].ranking);
        }
        system("pause");
        system("cls");
    }
    
    void menu5(struct SCHOOL *head)
    {                                                 //菜单5
        int output = 0, spoid, spflag, scaflag, flag; //spflag存下标,flag判断男1女2项目
        int i, j;
        struct SCHOOL *p, *q;
        Statotalscore(head);
        sortsportid(head, &spflag, &flag, 1, &output); //1降序
        if (flag == 1)
        {
            if (sportflag[spflag]) //男子项目取前五
            {
                p = head->next;
                while (p->spoman[spflag].ranking <= 5)
                {
                    printf("第%d名%s
    ", p->spoman[spflag].ranking, p->name);
                    p = p->next;
                }
            }
            else //男子项目取前三
            {
                p = head->next;
                while (p->spoman[spflag].ranking <= 3)
                {
                    printf("第%d名%s
    ", p->spoman[spflag].ranking, p->name);
                    p = p->next;
                }
            }
        }
        else if (flag == 2)
        {
            if (sportflag[spflag + SPORTMAN]) //女子项目取前五
            {
                p = head->next;
                while (p->spowoman[spflag].ranking <= 5)
                {
                    printf("第%d名%s
    ", p->spowoman[spflag].ranking, p->name);
                    p = p->next;
                }
            }
            else //女子项目取前三
            {
                p = head->next;
                while (p->spowoman[spflag].ranking <= 3)
                {
                    printf("第%d名%s
    ", p->spowoman[spflag].ranking, p->name);
                    p = p->next;
                }
            }
        }
        else
            printf("没有这个体育项目,请重新输入!
    ");
        system("pause");
        system("cls");
    }
    
    int main()
    {
        FILE *fp;
        int command, scaflag;
        struct SCHOOL *head, *p, *q;
        head = (struct SCHOOL *)malloc(sizeof(struct SCHOOL));
        head->next = NULL;
    
        while (1)
        {
            Mainmenu();
            printf("输入一个数选择功能:");
            scaflag = scanf("%d", &command);
            while (scaflag != 1)
            {
                fflush(stdin);
                system("cls");
                Mainmenu();
                printf("输入不是数字,请重新输入!
    ");
                scaflag = scanf("%d", &command);
            }
            if (command == 6)
                break;
            switch (command)
            {
            case 1:
                menu1makefile();
                break;
            case 2:
                system("cls");
                put_over_data(head);
                system("pause");
                system("cls");
                break;
            case 3:
                menu3sortput(head);
                break;
            case 4:
                menu4(head);
                break;
            case 5:
                menu5(head);
                break;
            default:
                printf("输入的命令有误,请重新输入!
    ");
                system("pause");
                system("cls");
                break;
            }
        }
        p = head;
        while (p)
        {
            q = p;
            p = q->next;
            free(q);
        }
        system("pause");
        return 0;
    }
    
  • 相关阅读:
    js把秒数转换为HH:MM:SS及时分秒格式
    java将流量KB转换为GB、MB、KB格式
    java将秒数转换为时分秒格式
    springboot前端向后端请求返回html语句
    java判断手机号三大运营商归属的工具类
    Java读取txt文件、excel文件的方法
    Linux安装JDK、Mysql和Tomcat
    原理篇—文件包含漏洞
    原理篇—上传漏洞
    原理篇—CSRF 跨站脚本请求伪造
  • 原文地址:https://www.cnblogs.com/yanhua-tj/p/13996582.html
Copyright © 2020-2023  润新知