学生管理系统C语言实现

近期做了一个学生管理系统,巩固了下文件io的知识!虽然只是一个小项目,不管对项目开发的认识有了一个小的提升。下面贴出各部分工作的代码。在codeblocks上编译完美运行。

先上图,程序运行后的菜单界面:

有基本的增删改查功能,还多了排序统计的辅助功能。

接下来分头文件和各个函数说明程序实现原理。

1.结构体头文件Studen.h(注意:头文件和.c文件不在同一个目录下,所以导入头文件时要使用绝对路径

该头文件定义了学生结构体,日期结构体和成绩结构体。

#ifndef STUDENT_H_INCLUDED
#define STUDENT_H_INCLUDED

/*头文件定义*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <process.h>
#include "Define.h"
#include "Function.h"

/*结构体定义*/
//成绩结构体
struct Score
{
	float C_score;          //c语言成绩
	float Database_score;   //数据库成绩
}SCORE;

//生日结构体
struct Birth
{
	int year;
	int month;
	int day;
}BIRTH;

//学生信息结构体
struct student
{
	char sex[3];            //性别
	int age;                //年龄
	char name[10];          //姓名
	char tel[15];           //电话
	char stu_no[5];         //学号
	float sum;              //成绩总和
	float avg;              //成绩平均值
	struct Birth birth;     //出生日期
	struct Score score;     //各项成绩
}STU[100];


#endif // STUDENT_H_INCLUDED

2.宏定义头文件Define.h

这个头文件定义了打印的输出格式,用一个变量代替一长串的输出格式,极大提高编程效率。注意各个变量的输出格式,例如整型的用%s输出,会造成不必要的错误。博主就在里面栽了跟头,都是很低级的错误。

#ifndef DEFINE_H_INCLUDED
#define DEFINE_H_INCLUDED

/*宏定义*/
#define LEN sizeof(struct student)  //结构体大小

//输出格式
#define FORMAT "%-5s%-9s%-5s%-5d%-14s%-4d-%-2d-%-5d%-7.1f%-7.1f%-7.1f%-7.1f\n"
#define DATA  STU[i].stu_no,STU[i].name,STU[i].sex,STU[i].age,STU[i].tel,STU[i].birth.year,STU[i].birth.month,STU[i].birth.day,\
                STU[i].score.C_score,STU[i].score.Database_score,STU[i].sum,STU[i].avg


#endif // DEFINE_H_INCLUDED

3.函数实现头文件Function.h

这个头文件声明各个函数。

#ifndef FUNCTION_H_INCLUDED
#define FUNCTION_H_INCLUDED

//#include "Student.h"
/*函数声明*/
void In();          //输入学生信息
void Show();        //显示学生信息
void Order();       //排序
void Del();         //删除
void Modify();      //修改
void Menu();        //菜单
void Insert();      //插入
void Total();       //总数
void Seek();        //查找


#endif // FUNCTION_H_INCLUDED

接下来是.c文件的实现。 再次注意包含的头文件的路径,因为不是在一个工程目录下。

1.主函数main.c

主函数的作用就是打印菜单和接收用户的选择,并跳转到相应函数的实现。

#include "../inc/Student.h"
#include "../inc/Function.h"
int main(void)
{
    int n;
    Menu();
    scanf("%d",&n);
    while(n)
    {
        switch(n)
        {
            case 1: In(); break;
            case 2: Seek(); break;
            case 3: Del(); break;
            case 4: Modify(); break;
            case 5: Insert(); break;
            case 6: Order(); break;
            case 7: Total(); break;
            case 8: Show(); break;
            default :break;
        }
    getch();    //会等待你按下任意键,再继续执行下面的语句;
    Menu();     //执行完所选功能再次打印菜单
    scanf("%d",&n);
    }
    //printf("Goodbye!\n");
    printf("\n\t|------------------------感谢你的使用!-------------------------|\n");
    return 0;
}

2.函数功能实现function.h

(1)包含需要的头文件:(再再次强调绝对路径)

#include "../inc/Student.h"
#include "../inc/Function.h"
#include "../inc/Define.h"

(2)菜单 void Menu()

只用来打印菜单

void Menu()
{
    system("cls");
    printf("\n\n\n\n");
    printf("\t|-------------------------学生管理系统--------------------------|\n");
    printf("\t|                                                               |\n");
    printf("\t|\t\t\t  0.退出                                |\n");
    printf("\t|\t\t\t  1.输入学生信息                        |\n");
    printf("\t|\t\t\t  2.查找学生信息                        |\n");
    printf("\t|\t\t\t  3.删除学生信息                        |\n");
    printf("\t|\t\t\t  4.修改学生信息                        |\n");
    printf("\t|\t\t\t  5.插入学生信息                        |\n");
    printf("\t|\t\t\t  6.排序                                |\n");
    printf("\t|\t\t\t  7.学生人数                            |\n");
    printf("\t|\t\t\t  8.显示学生信息                        |\n");
    printf("\t|                                                               |\n");
    printf("\t|         作者:RongXiangXing       时间:2017/6/11             |\n");
    printf("\t|---------------------------------------------------------------|\n");
    printf("\t\t\t输入0-8选择相应的功能: ");
}

(3)输入学生信息函数 void In()

先到指定的文件中查看是否还有记录,如果没有记录,就打印没有记录的提示信息;有过有记录,就将已有记录显示出来。

void In()       //输入学生信息函数
{
    int i,m = 0;        //m是记录行数
    char ch[2];
    FILE *fp;       //定义文件指针
    if((fp = fopen("Database.txt","a+")) == NULL)
    {
        printf("无法代开文件!\n");
        return ;
    }
    while(!feof(fp))        //feof(fp)表示到达文件末尾
    {
        if(fread(&STU[m],LEN,1,fp) == 1)    //若成功则返回实际读入的count数据,即1
            m++;            //记录条数增加
    }
    fclose(fp);             //关闭文件
    if( m == 0)
        printf("没有记录!\n");
    else
    {
        system("cls");        //清屏
        Show();
    }
    if((fp = fopen("Database.txt","wb")) == NULL)
    {
        printf("无法代开文件!\n");
        return ;
    }
    for(i = 0 ; i < m ; i++)
        fwrite(&STU[i],LEN,1,fp);       //向指定的磁盘文件写入信息
    printf("是否输入学生信息(y/n):");
    scanf("%s",ch);
    while(strcmp(ch,"Y") == 0 || strcmp(ch,"y") == 0)   //判断是否要输入信息
    {
        printf("学号:");
        scanf("%s",STU[m].stu_no);  //数组名就是首地址
        for( i = 0 ; i < m ; i++)
        {
            if(STU[i].stu_no == STU[m].stu_no)
            {
                printf("该学号已存在,请重新输入或将已有学号信息删除再输入!");
                getch();//会等待你按下任意键,再继续执行下面的语句;
                fclose(fp);
                return ;
            }
        }
        printf("姓名:");
        scanf("%s",STU[m].name);    //输入姓名
        printf("性别:");
        scanf("%s",STU[m].sex);     //输入性别,非数组要用取地址符&
        printf("年龄:");
        scanf("%d",&STU[m].age);    //输入年龄
        printf("电话:");
        scanf("%s",STU[m].tel);     //输入电话
        printf("出生日期:");
        scanf("%d%d%d",&STU[m].birth.year,&STU[m].birth.month,&STU[m].birth.day);//输入出生日期
        printf("C语言成绩:");
        scanf("%f",&STU[m].score.C_score);//输入C语言成绩
        printf("数据库成绩:");
        scanf("%f",&STU[m].score.Database_score);//输入数据库成绩
        STU[m].sum = STU[m].score.C_score + STU[m].score.Database_score;  //计算成绩总和
        STU[m].avg = STU[m].sum / 2.0;  //计算平均值
        if(fwrite(&STU[m],LEN,1,fp) != 1)
        {
            printf("无法存储信息,请检查输入格式!");
            getch();
        }
        else
        {
            printf("%s号学生信息已保存!\n",STU[m].stu_no);
            m++;        //记录增加
        }
        printf("是否继续录入信息?(y/n):");
        scanf("%s",ch);
    }
    fclose(fp);
    printf("输入操作完成,按任意键进入主菜单!\n");
}

运行界面:



(4)查询学生信息函数void Seek()

先按学号查询,如果没有找到,则提示使用姓名查询,若果仍没找到,打印提示信息。若找到则打印学生信息。

void Seek()     //查询学生信息函数
{
    FILE *fp;
    char ch[2],snum[5],sname[10];
    int i,m = 0;
    if((fp = fopen("Database.txt","rb")) == NULL)   //以只读方式打开文件
    {
        printf("无法代开文件!\n");
        return ;
    }
    while(!feof(fp))        //feof(fp)表示到达文件末尾
    {
        if(fread(&STU[m],LEN,1,fp) == 1)    //若成功则返回实际读入的count数据,即1
            m++;            //记录条数增加
    }
    fclose(fp);
    if(m == 0)
    {
        printf("没有记录!\n");
        return ;
    }
    printf("请输入要查询的学号:");
    scanf("%s",snum);
    for(i=0;i<m;i++)
    {
        if(strcmp(snum,STU[i].stu_no) == 0)
        {
            printf("学号  姓名   性别  年龄     电话       出生日期   C语言  数据库   sum   avg\n");
            printf(FORMAT,DATA);        //若找到按指定格式输出信息
            break;
        }
    }
    if(i == m)
    {
        printf("没有找到这名学生的记录!\n");
        printf("是否尝试进行姓名查找?(y/n):");
        scanf("%s",ch);
        for(i=0;i<m;i++)
        {
            if(strcmp(ch,"Y") == 0 || strcmp(ch,"y") == 0)
            {
                printf("请输入要查找学生的姓名:");
                scanf("%s",sname);
                if(strcmp(sname,STU[i].name) == 0)
                {
                    printf("学号  姓名   性别  年龄     电话       出生日期   C语言  数据库   sum   avg\n");
                    printf(FORMAT,DATA);        //若找到按指定格式输出信息
                    break;
                }
                else
                {
                    printf("仍然无法找到这名学生的记录!\n");
                    break;
                }
            }
        }
    }
    printf("查询操作完成,按任意键进入主菜单!\n");
}

运行界面:



(5)删除学生信息函数 void Del()

如果找到学生信息,提示是否删除。没找到则打印没有该学生信息。

void Del()      //删除学生信息函数
{
    FILE *fp;
    char ch[2],snum[5];
    int i,j,m = 0;
    if((fp = fopen("Database.txt","r+")) == NULL)   //以可读写方式打开文件
    {
        printf("无法代开文件!\n");
        return ;
    }
    while(!feof(fp))        //feof(fp)表示到达文件末尾
    {
        if(fread(&STU[m],LEN,1,fp) == 1)    //若成功则返回实际读入的count数据,即1
            m++;            //记录条数增加
    }
    fclose(fp);
    if(m == 0)
    {
        printf("没有记录!\n");
        return ;
    }
    printf("请输入要删除记录的学生学号:");
    scanf("%s",snum);
    for(i=0;i<m;i++)
    {
        if(strcmp(snum,STU[i].stu_no) == 0) //如果找到这个学生的记录
            break;
    }
    printf("学生记录已找到,是否确定删除?(y/n):");
    scanf("%s",ch);
    if(strcmp(ch,"Y") == 0 || strcmp(ch,"y") == 0)
    {
        for(j=i;j<m;j++)
        {
            STU[j] = STU[j+1];      //后面记录的信息往前移,删除该条记录
            m--;        //记录条数减少
        }
    }
    if((fp = fopen("Database.txt","wb")) == NULL)   //重新写入操作后的记录
    {
        printf("无法代开文件!\n");
        return ;
    }
    for(j=0;j<m;j++)
    {
        if(fwrite(&STU[j],LEN,1,fp) != 1)
        {
            printf("写入信息失败!\n");
            getch();
        }
    }
    fclose(fp);
    printf("删除操作完成,按任意键进入主菜单!\n");
}

运行界面:



(6)修改学生信息函数 void Modify()

若找到要修改的学生信息的记录,则提示修改的各项信息,若没有找到,则打印查无此人的信息。

void Modify()   //修改学生信息函数
{
    FILE *fp;
    int i,j,m = 0;
    char snum[5];
    if((fp = fopen("Database.txt","r+")) == NULL)   //以可读写方式打开文件
    {
        printf("无法代开文件!\n");
        return ;
    }
    while(!feof(fp))        //feof(fp)表示到达文件末尾
    {
        if(fread(&STU[m],LEN,1,fp) == 1)    //若成功则返回实际读入的count数据,即1
            m++;            //记录条数增加
    }
    fclose(fp);


    Show();
    printf("请输入你想要修改信息的学生学号:");
    scanf("%s",snum);
    for(i=0;i<m;i++)
    {
        if(strcmp(snum,STU[i].stu_no) == 0)
        {
            printf("找到该学生的记录,现在你能进行更新信息!\n");
            printf("姓名:");
            scanf("%s",STU[i].name);    //输入姓名
            printf("性别:");
            scanf("%s",STU[i].sex);     //输入性别,非数组要用取地址符&
            printf("年龄:");
            scanf("%d",&STU[i].age);    //输入年龄
            printf("电话:");
            scanf("%s",STU[i].tel);     //输入电话
            printf("出生日期:");
            scanf("%d%d%d",&STU[i].birth.year,&STU[i].birth.month,&STU[i].birth.day);//输入出生日期
            printf("C语言成绩:");
            scanf("%f",&STU[i].score.C_score);//输入C语言成绩
            printf("数据库成绩:");
            scanf("%f",&STU[i].score.Database_score);//输入数据库成绩
            STU[i].sum = STU[i].score.C_score + STU[i].score.Database_score;  //计算成绩总和
            STU[i].avg = STU[i].sum / 2.0;  //计算平均值
            printf("学生信息修改成功!\n");
            break;
        }
    }
    if(i == m)
    {
        printf("没有找到该学生的记录!\n");
    }
    if((fp = fopen("Database.txt","wb")) == NULL)   //重新写入操作后的记录
    {
        printf("无法代开文件!\n");
        return ;
    }
    for(j=0;j<m;j++)        //将修改后的信息重新写入磁盘文件
    {
        if(fwrite(&STU[j],LEN,1,fp) != 1)
        {
            printf("写入信息失败!\n");
            getch();
        }
    }
    fclose(fp);
    printf("修改操作完成,按任意键进入主菜单!\n");
}

运行界面:



(7)插入学生信息函数

在要插入的学号的后面插入学生信息。

void Insert()   //插入学生信息函数
{
    FILE *fp;
    int i,j,k,m = 0;
    char snum[5];
    if((fp = fopen("Database.txt","r+")) == NULL)   //以可读写方式打开文件
    {
        printf("无法代开文件!\n");
        return ;
    }
    while(!feof(fp))        //feof(fp)表示到达文件末尾
    {
        if(fread(&STU[m],LEN,1,fp) == 1)    //若成功则返回实际读入的count数据,即1
            m++;            //记录条数增加
    }
    fclose(fp);
    if(m == 0)
    {
        printf("没有记录!\n");
        return ;
    }
    printf("请输入你想要插入的学号的位置(是在输入的学号后面插入):");
    scanf("%s",snum);
    for(i=0;i<m;i++)
    {
        if(strcmp(snum,STU[i].stu_no) == 0)
        {
            printf("找到要插入的学生的位置!现在你可以插入学生信息!\n");
            for(j=m-1;j>i;j--)
            {
                STU[j+1] = STU[j];      //从最后一条记录开始向后移,为要插入的信息提供空间
            }
            printf("学号:");
            scanf("%s",STU[i+1].stu_no);  //数组名就是首地址
            for(k=0 ; k<m ; k++)
            {
                if(STU[k].stu_no == STU[i+1].stu_no)
                {
                    printf("该学号已存在,请重新输入或将已有学号信息删除再输入!");
                    getch();//会等待你按下任意键,再继续执行下面的语句;
                    fclose(fp);
                    return ;
                }
            }
            printf("姓名:");
            scanf("%s",STU[i+1].name);    //输入姓名
            printf("性别:");
            scanf("%s",STU[i+1].sex);     //输入性别,非数组要用取地址符&
            printf("年龄:");
            scanf("%d",&STU[i+1].age);    //输入年龄
            printf("电话:");
            scanf("%s",STU[i+1].tel);     //输入电话
            printf("出生日期:");
            scanf("%d%d%d",&STU[i+1].birth.year,&STU[i+1].birth.month,&STU[i+1].birth.day);//输入出生日期
            printf("C语言成绩:");
            scanf("%f",&STU[i+1].score.C_score);//输入C语言成绩
            printf("数据库成绩:");
            scanf("%f",&STU[i+1].score.Database_score);//输入数据库成绩
            STU[i+1].sum = STU[i+1].score.C_score + STU[i+1].score.Database_score;  //计算成绩总和
            STU[i+1].avg = STU[m].sum / 2.0;  //计算平均值
            printf("成功插入学生信息!\n");
        }
    }
    if((fp = fopen("Database.txt","wb")) == NULL)   //重新写入操作后的记录
    {
        printf("无法代开文件!\n");
        return ;
    }
    for(k=0;k<=m;k++)        //将修改后的信息重新写入磁盘文件,因为插入后记录加1,所以这里是<=m
    {
        if(fwrite(&STU[k],LEN,1,fp) != 1)
        {
            printf("写入信息失败!\n");
            getch();
        }
    }
    fclose(fp);
    printf("插入操作完成,按任意键进入主菜单!\n");
}

运行界面:



(8)按成绩总和排序学生信息void Order()  (也可以自己尝试按单科成绩排名)

void Order()    //排序学生信息
{
    FILE *fp;
    struct student t;   //定义student结构体对象,用于交换记录
    int i=0,j=0,m=0;
    if((fp = fopen("Database.txt","r+")) == NULL)   //以可读写方式打开文件
    {
        printf("无法代开文件!\n");
        return ;
    }
    while(!feof(fp))        //feof(fp)表示到达文件末尾
    {
        if(fread(&STU[m],LEN,1,fp) == 1)    //若成功则返回实际读入的count数据,即1
            m++;            //记录条数增加
    }
    fclose(fp);
    if(m == 0)
    {
        printf("没有记录!\n");
        return ;
    }
    if((fp = fopen("Database.txt","wb")) == NULL)   //重新写入操作后的记录
    {
        printf("无法代开文件!\n");
        return ;
    }
    for(i=0;i<m;i++)        //使用冒泡排序法进行排序
    {
        for(j=0;j<m-i-1;j++)
        {
            if(STU[j].sum < STU[j+1].sum)
            {
                t = STU[j];
                STU[j] = STU[j+1];
                STU[j+1] = t;
            }
        }
    }
    if((fp = fopen("Database.txt","wb")) == NULL)   //重新写入操作后的记录
    {
        printf("无法代开文件!\n");
        return ;
    }
    for(i=0;i<m;i++)        //将修改后的信息重新写入磁盘文件,因为插入后记录加1,所以这里是<=m
    {
        if(fwrite(&STU[i],LEN,1,fp) != 1)
        {
            printf("写入信息失败!\n");
            getch();
        }
    }
    fclose(fp);
    printf("排序操作完成,按任意键进入主菜单后可按8显示功能查看!\n");
}

运行界面:



(8)求总人数函数void Total(),其实就是求出文件中的记录数

void Total()    //求总人数
{
    FILE *fp;
    int m=0;
    if((fp = fopen("Database.txt","r+")) == NULL)   //以可读写方式打开文件
    {
        printf("无法代开文件!\n");
        return ;
    }
    while(!feof(fp))        //feof(fp)表示到达文件末尾
    {
        if(fread(&STU[m],LEN,1,fp) == 1)    //若成功则返回实际读入的count数据,即1
            m++;            //记录条数增加
    }
    fclose(fp);
    if(m == 0)
    {
        printf("没有记录!\n");
        return ;
    }
    Show();
    printf("总共有 %d 名学生的信息!\n",m);
    printf("按任意键进入主菜单!\n");
}

运行界面: (打印出的学生信息,就是上一步已排序好的信息)



(9)显示学生信息函数void Show()

将文件中所有的学生信息记录打印出来。

void Show()     //显示已有记录
{
    FILE *fp;
    int i,m = 0;
    fp = fopen("Database.txt","rb");//以只读方式打开二进制流文件,打开二进制文件是因为速度快
    while(!feof(fp))
    {
        if(fread(&STU[m],LEN,1,fp) == 1)
            m++;
    }
    fclose(fp);
    printf("学号  姓名   性别  年龄     电话       出生日期   C语言  数据库   sum   avg\n");
    for(i = 0 ; i < m ; i++)
    {
        printf(FORMAT,DATA);    //将录入的信息按指定格式输出

    }
}

运行界面:



(10)退出程序

这一部分的代码其实就在main.c中,读者自己去体会吧,这里不做过多说明。



至此,学生管理系统程序实现和功能验证已完成。代码难度适中,读者可以自己去细心体会。博主还是在校大学生,实践能力不足,有错误的地方还请大家批评指正,共同进步!

  • 8
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值