C语言——学生管理系统的实现

 项目要求:

1、结构体  2、分文件  3、make编译

(1)系统运行时,打开如下界面。列出系统帮助菜单(即命令菜单),提示输入命令。

(2) 开始时还没有录入成绩,除了输入命令T进行成绩录入,输入其他命令无法列出成绩。应提示“成绩表为空!请先使用命令 T 录入学生成绩。”

(3)输入命令 T,调用Type子函数录入成绩。界面提示输入学生人数,提示输入n名学生的3门课成绩,列出成绩单的表头“学号 语文 数学 英语”,提示学号:1。输入完毕后,按回车结束。Type子函数调用结束,返回。提示输入命令。

(4)输入命令 L ,调用List子函数输出成绩表。List子函数调用结束,返回。提示输入命令。

(5)输入命令 A ,调用Average子函数计算平均分,提示“平均分已计算。请使用命令L查看。” Average子函数调用结束,返回。提示输入命令。再次输入命令 L ,调用List子函数输出成绩表。List子函数调用结束,返回。提示输入命令。

(6)输入命令 P ,调用Sort子函数将各学生记录按平均分由高到低排序,提示“完成排序。请使用命令L查看。” Sort子函数调用结束,返回。提示输入命令。再次输入命令 L ,调用List子函数输出成绩表。List子函数调用结束,返回。提示输入命令。

(7)输入命令 S ,调用Search子函数查询学生成绩,提示“输入要查询的学生学号”。输入2 ¿ 找到2号学生的成绩并输出。Search子函数调用结束,返回。提示输入命令。

(8)输入命令C,执行清屏函数语句system("clear");清除屏幕的所有内容。提示输入命令

(9)输入命令H,调用Help子函数显示帮助菜单。Help子函数调用结束,返回。提示输入命令。

(10)输入命令Q,退出系统。

注意:

        (1)输出数组元素时,要将学号单独处理,输出为整数(即保留0位小数)。同理,在计算成绩时也要将第1列的学号撇开,只计算第2列之后的。成绩保留1位小数。

        (2)学生人数n贯穿始终,通过n的值判断当前命令的子函数是否能够调用执行。例如:当n=0时,说明还没有录入成绩。而一旦输入命令T,也即调用Type子函数录入了成绩,则n的值就不再是0。当n!=0时,就可以进行其他的成绩操作,但不能再执行录用成绩的操作。所以当用户输入的命令无法执行时,应当给出提示。

项目代码:

头文件:

        头文件一般不声明变量,可以在其他源文件内先声明变量,在头文件中外部引用,在其他子函数内引用头文件。

        因为定义的结构体和声明的外部变量都在头文件中,所以无需在每个函数调用时显式地传递这些参数或变量(外部引用------牵一发而动全身)。

#ifndef __HEAD_H_
#define __HEAD_H_
typedef struct student
{
    int num;//学号
    float chinese;
    float math;
    float english;
}STU;//存储学生信息
STU SCORE[100];
extern float average[100];//平均数数组
extern int num; // 全部变量学生个数
extern char n;  // 菜单编号
void menu();
void type();
void help();
void list();
void sort();
void serch();
void clean();
void Average();

#endif

主函数:

        主要使用switch case分支语句来判断是否输入正确命令,并调用子函数

#include <stdio.h>
#include "head.h"

int num; // 全部变量学生个数
char n;  // 菜单编号

int main()
{
    menu();
    n=toupper(n);
    while (n != 'Q'||n!='q')//输入Q时退出程序
    {
        
        printf("请输入指令=");
        scanf(" %c", &n);
        switch (n)
        {
        case 'H':
        case 'h':
            help();
            break;
        
        case 'T':
        case 't':
            if (num == 0)
                type();
            else
                printf("你已经录入学生信息,请勿重复录入\n");
            break;
        case 'A':
        case 'a':
            if (num > 0)
                Average();
            else
                printf("成绩表为空!请先使用命令 T 录入学生成绩。\n");
            break;
        case 'L':
        case 'l':
            if (num > 0)
                list();
            else
                printf("成绩表为空!请先使用命令 T 录入学生成绩。\n");
            break;
        case 'P':
        case 'p':
            if (num > 0)
                sort();
            else
                printf("成绩表为空!请先使用命令 T 录入学生成绩。\n");
            break;
        case 'S':
        case 's':
            if (num > 0)
                serch();
            else
                printf("成绩表为空!请先使用命令 T 录入学生成绩。\n");
            break;
        case 'C':
        case 'c':
            clean();
            break;
        case 'Q':
        case 'q':
            printf("退出程序\n");
            return 0;
        default:
            printf("输入错误,请重新输入!\n");
            break;
        }
    }
return 0;
}

创建菜单:

        创建菜单的子函数比较简单,可以新封装一个函数专门用来输出*号,这样看起来干净清爽很多。

注意对齐!!!

#include<stdio.h>
#include"head.h"
void str()
{
    for(int i=0;i<50;i++)
        printf("*");
    printf("\n");
}//*号输出机
void menu()
{
    str();
    printf("  *      学生管理系统--帮助菜单                *\n");
    str();
    printf("  *        H = 显示帮助菜单                    *\n");
    printf("  *        T = 成绩录入                        *\n");
    printf("  *        A = 计算学生平均分                  *\n");
    printf("  *        L = 列出成绩表                      *\n");
    printf("  *        P = 按平均成绩由高到低排序          *\n");
    printf("  *        S = 按学号查询学生成绩              *\n");
    printf("  *        C = 清屏                            *\n");
    printf("  *        Q = 退出系统                        *\n");
    str();
    printf("  *     Copyright <C> 2024.07.11 by 靳长庚     *\n");
    str();
}

帮助菜单

#include<stdio.h>
#include"head.h"
extern void str();
void help()
{
    str();
    printf("  *      学生管理系统--帮助菜单                *\n");
    str();
    printf("  *        H = 显示帮助菜单                    *\n");
    printf("  *        T = 成绩录入                        *\n");
    printf("  *        A = 计算学生平均分                  *\n");
    printf("  *        L = 列出成绩表                      *\n");
    printf("  *        P = 按平均成绩由高到低排序          *\n");
    printf("  *        S = 按学号查询学生成绩              *\n");
    printf("  *        C = 清屏                            *\n");
    printf("  *        Q = 退出系统                        *\n");
    str();
    printf("  *     Copyright <C> 2024.07.11 by 靳长庚     *\n");
    str();

}

成绩录入

           输入命令T后,提示输入学生人数,输出表头。

    printf("请输入学生人数:");
    scanf(" %d",&num);
    printf("请输入%d个学生的3门课成绩:\n",num);
    printf("学号\t语文\t数学\t英语\n");

        使用for循环遍历输入学生成绩,同时提供学号提示,并赋值给结构体数组。(在排序和输出成绩表时使用。)

#include<stdio.h>
#include"head.h"

void type()
{
    printf("请输入学生人数:");
    scanf(" %d",&num);
    printf("请输入%d个学生的3门课成绩:\n",num);
    printf("学号\t语文\t数学\t英语\n");
    
    for(int i=0;i<=num-1;i++)
    {
        printf("%d",i+1);//提示学号
        SCORE[i].num=i+1;
        scanf("%f %f %f",&SCORE[i].chinese,&SCORE[i].english,&SCORE[i].math);
    }
    printf("成绩录入完毕\n");
}

计算学生平均分

        定义了一个平均数的数组,同时在头文件内声明外部引用该平均数数组,简化函数传参。

        使用for循环,循环计算每一个学生的平均分

#include<stdio.h>
#include"head.h"

float average[100];//平均数数组
void Average()
{   
    for(int i=0;i<num;i++)
        average[i] = (SCORE[i].chinese+SCORE[i].english+SCORE[i].math)/3 ;
    printf("平均分已计算。请使用命令L查看。\n");
}

排序

        当没有计算平均分时,无法进行排序,并给出提示,回到主函数。

        使用冒泡排序,将平均分较高的学生往前冒泡,同时也需要交换学号。(对应成绩录入时写入学号/🙂)

#include<stdio.h>
#include"head.h"
void sort()
{
    if (average[0]!=0)
    {
    float *p=average;
    for(int i=0;i<num-1;i++)
    {
        for(int j=0;j<num-1-i;j++)
        {
            if(p[j+1]>p[j])
            {
                STU temp = SCORE[j];//定义结构体变量,分别存入对应成员变量
                SCORE[j] = SCORE[j + 1];
                SCORE[j+1] = temp;

                float temp1=p[j];
                p[j]=p[j+1];
                p[j+1]=temp1;
            }
        }
    }
    printf("排序已完成,请按L查看。\n");
    }else if(average[0]==0)
    {
        printf("请先输入命令A计算平均分。\n");
        return;
    }
}

列出成绩表

        成绩表采用多层if结构:如果没有计算平均分(平均分数组内所有元素都是0,以此来当if条件语句),输出表头不应该带平均分那一列,如果进行了平均分的计算后,则输出列应该有平均分。      

        采用for循环,循环遍历输出结构体数组成员。

/*输出成绩表*/
#include<stdio.h>
#include"head.h"
extern int s;//引用sort中定义的s来判断是否执行了排序函数
void list()
{
    if(average[0]==0)
    {
    printf("学生成绩如下:\n");
    printf("学号\t语文\t数学\t英语\n");
    for(int i=0;i<=num-1;i++)
        {
        printf("%d",SCORE[i].num);
        printf("\t%0.1f\t%0.1f\t%0.1f\n",SCORE[i].chinese,SCORE[i].english,SCORE[i].math);
        }
    }
    else if(average[0]!=0)
    {
        printf("学号\t语文\t数学\t英语\t平均分\n");
        for(int i=0;i<=num-1;i++)
        {
        printf("%d",SCORE[i].num);
        printf("\t%0.1f\t%0.1f\t%0.1f\t%0.1f\n",SCORE[i].chinese,SCORE[i].english,SCORE[i].math,average[i]);
        }
}
}

查询学生成绩

        定义一个变量id,用来向用户索取要查询的学生号,进入循环(当输入错误时循环向用户索取学生id),当输入id在学生人数范围内时,对学生id进行遍历,查找到符合的学号时输出该学生的成绩并返回主函数等待命令。

#include<stdio.h>
#include"head.h"

int id=0;
void serch()
{    
    printf("输入要查询的学生学号:");
    scanf(" %d",&id);
    while(1)
    {
        if (id >= 1 && id <= num)
        {
            for(int i=0;i<num;i++)
            {   
                if(id==SCORE[i].num)
                {
              
                    printf("学号\t语文\t数学\t英语\t平均分\n");
                    printf("%d",SCORE[i].num);
                    printf("\t%0.1f\t%0.1f\t%0.1f\t%0.1f\n",SCORE[i].chinese,SCORE[i].english,SCORE[i].math,average[i]);
                    return;

                }
            }
        }else
            {
                printf("输入错误,查无此人,请重新输入:");
                scanf(" %d",&id);
            }
    }
}

清屏

        使用system("clear")函数,注意头文件是<stdlib.h>

#include<stdio.h>
#include <stdlib.h> 
void clean()
{
    system("clear");
    return;
}

make编译

CC=gcc
OBJS=main.o menu.o help.o type.o list.o average.o sort.o serch.o clean.o
CFLAGS=-c -g -Wall
main: $(OBJS)
	$(CC) $^ -o $@

%.o: %.c
	$(CC) $(CFLAGS) $< -o $@

.PHONY: clean
clean:
	$(RM) -r *.o main  

效果展示

C语言-学生管理系统的实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值