C语言课程设计——学生信息管理系统

学生信息管理

(1)问题描述

       学生信息包括:学号,姓名,年龄,性别,出生年月,地址,电话,E-mail等。试设计一学生信息管理系统,使之能提供以下功能:

  1. 系统以菜单方式工作
  2. 学生信息录入功能(学生信息用文件保存)---输入
  3. 学生信息浏览功能——输出
  4. 查询、排序功能——算法

1、按学号查询

2、按姓名查询

  1. 学生信息的删除与修改(可选项)

       (2)功能要求

  1. 界面简单明了;
  2. 有一定的容错能力,比如输入的成绩不在0~100之间,就提示不合法,要求重新输入;
  3. 最好用链表的方式实现。

(3)算法分析

首先,一个学生包括这么多的属性,应该考虑定义一个结构,其次,我们应该考虑数据的存储形式:是定义一个数组来存储,还是定义一个链表呢?在这里假如我们以数组的方式来存储,当然可以,但是我们知道,假如我们定义一个数组的话,我们首先必须知道学生人数大概是多少,以便我们确定数组的大小,但是题目中没有给出,而且题目要求中有大量的删除、插入操作,所以用链表的方式比较方便。

效果展示:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>

typedef struct Student //学生信息包括:学号,姓名,年龄,性别,出生年月,地址,电话,E-mail。
{
    int number;
    char name[20];
    int age;
    char sex[6];
    char birthday[12];
    char address[20];
    char phone[12];
    char email[20];
    struct Student *next;
} Student;

void menu();//函数声明
Student *Read();
void Write(Student *head);
void Scan(Student *current);
Student *Sort(Student *head);
Student *Input();
Student *Delete(Student *head);
Student *Add(Student *head);
void Show(Student *head);
Student *Find(Student *head);
Student *Find(Student *head);
Student *Change(Student *headI);

Student *Read()//从文件读出链表的函数
{
    Student *head=NULL,*pre=NULL,*current=NULL;
    FILE *fp;
    if(!(fp=fopen("date.txt","rb"))) 	//打开文件
    {
        printf("此文件不可打开!");
        system("pause");
        return head;
    }

    char ch=fgetc(fp);
    rewind(fp);//此处很重要,如果丢失了就会出错 ,因为上一条语句后fp不是指向文件开头了
    if(ch!=EOF) //判断:判断文件是否为空,解决文件为空的情况
    {
        head=pre=current=(Student *)malloc(sizeof(Student));//创建链表
        fread(current,sizeof(Student),1,fp);
        while(current->next)
        {
            pre=current;
            current=(Student *)malloc(sizeof(Student));
            pre->next=current;
            fread(current,sizeof(Student),1,fp);
        }
    }
    else
    {
        printf("此文件为空,请先输入数据");//提示
        system("pause");
    }
    fclose(fp);//关闭文件
    menu();//刷新界面
    return head;
}

void Write(Student *head) //写入数据函数:把数据写入到磁盘中
{
    FILE *fp;
    if(!(fp=fopen("date.txt","wb"))) //打开并准备重写文件
    {
        printf("此文件不可打开!");
        system("pause");
        return;
    }

    while(head) //写入数据
    {
        fwrite(head,sizeof(Student),1,fp);
        head=head->next;
    }

    fclose(fp);
}

void Scan(Student *current)//输入数据,在其他地方可调用
{
    printf("姓名: ");//name
    scanf("%s",&current->name);

    printf("年龄: ");//age
    scanf("%d",&current->age);
    while((current->age > 120)||(current->age < 0))//判断是否为合法输入
    {
        printf("输入错误,重新输入年龄:");
        scanf("%d",&current->age);
    }
    printf("性别: ");//sex
    scanf("%s",&current->sex);
    printf("生日: ");//birthday
    scanf("%s",&current->birthday);
    printf("地址: ");//address
    scanf("%s",&current->address);
    printf("电话: ");//phone
    scanf("%s",&current->phone);
    printf("邮箱: ");//email
    scanf("%s",&current->email);
}

Student *Input()//信息录入与保存函数
{
    puts("输入学号为0结束");//学号输0表示结束
    Student *head=NULL,*pre=NULL,*current=NULL;
    head=pre=current=(Student *)malloc(sizeof(Student));

    printf("学号: ");
    scanf("%d",&current->number);
    if(current->number) Scan(current);
    else head=NULL;
    while(current->number)
    {
        pre=current;
        current=(Student *)malloc(sizeof(Student));
        printf("学号: ");
        scanf("%d",&current->number);
        if(!current->number)
        {
            printf("---输入完成---");
            system("pause");
            break;
        }
        Scan(current);
        pre->next=current;
    }
    pre->next=NULL;

    head=Sort(head);//排序
    Write(head);//重写
    return head;
}

Student *Sort(Student *head)//排序函数
{
    if(head) //判断
    {
        Student *pre,*current,*next;
        pre=current=head;
        next=head->next;
        int count=0;
        while(head) //计算一共有多少条数据
        {
            head=head->next;
            count++;
        }
        head=current;//头返回起点

        int i,j,flag;
        for(i=count-1; i>0; i--) //冒泡排序法实现
        {
            flag=1;
            for(j=0; j<i; j++)
            {
                if(current->number>next->number)
                {
                    current->next=next->next;
                    next->next=current;
                    if(j) //不是首节点
                        pre->next=next;
                    else
                        head=next;
                }
                current=current->next;
                next=next->next;
                if(j)
                    pre=pre->next;
                flag=0;
            }
            pre=current=head;
            next=head->next;
            if(flag)
                break;
        }
    }
    else
    {
        printf("此文件为空,请先输入数据");//提示
        system("pause");
    }
    return head;
}

Student *Delete(Student *head)//删除数据
{
    if(head) //判断 ,当文件夹为空(链表为空的时候)
    {
        int num,j=1;
        puts("请输入您想要删除的学生的学号");
        scanf("%d",&num);

        Student *pre=head,*current=head;
        int count=1;
        while(current->number!=num) //寻找要删除的数据
        {
            count++;
            pre=current;
            current=current->next;
            if(!current)
            {
                j=0;
                break;
            }
        }

        if(j) //准备删除
        {
            if(count==1)
            {
                head=head->next;
                free(pre);
            }
            else
            {
                pre->next=current->next;
                free(current);
            }
            Write(head);
            printf("\n");
            printf("---删除成功!---\n");
            printf("\n");
            printf(">>>现在的学生信息为:\n");
            Show(head);
        }
        else
        {
            printf("不存在此人!");
            system("pause");
        }
    }
    else
    {
        printf("此文件为空,请先输入数据");//空文件
        system("pause");
    }
    return head;
}

Student *Add(Student *head)//添加数据:按排序插入
{
    Student *pre=head,*current=head;
    Student *p=(Student*)malloc(sizeof(Student));
    printf("学号:");
    scanf("%d",&p->number);
    Scan(p);

    if(head) //判断,防止文件夹为空
    {
        if( p->number  <=  head->number )
        {
            p->next=head;
            head=p;
        }
        else
        {
            current=current->next;
            while(current)
            {
                if( p->number  <=  current->number )
                {
                    pre->next=p;
                    p->next=current;
                    break;
                }
                else
                {
                    pre=current;
                    current=current->next;
                }
            }
            if(!current)
            {
                pre->next=p;
                p->next=NULL;
            }
        }
    }
    else
    {
        head=p;
        head->next=NULL;
    }

    Write(head);
    printf("---添加成功!---\n");
    printf("\n");
    printf(">>>现在的学生信息为:\n");
    Show(head);
    return head;//如果插入在第一个以前,则head变了,于是需要返回head
}

void Show(Student *head) //浏览数据
{
    int n=1;
    if(head)
    {
        printf("*************************************************************************************************************************\n");
        printf("║序号 ║║    学号  ║    姓名  ║  年龄   ║    性别  ║     出生年月    ║║   地址    ║║    电话    ║║      邮箱     ║\n");
        while(head)
        {
            printf(" %d\t   %d\t     %s\t   %d\t    %s\t      %s\t       %s\t      %s\t    %s\n ",
                   n,head->number,head->name,head->age,head->sex,head->birthday,head->address,head->phone,head->email);
            head=head->next;
            n++;
        }
        printf("*************************************************************************************************************************\n");

    }
    else
        printf("此文件为空,请先输入数据");
    system("pause");
}

void findmenu()
{
    printf("\n\n\n");
    printf("\t\t\t☆☆学生信息查找☆☆\n");
    printf("\t\t---------------------------------------\n");
    printf("\t\t\t  1 按学号查找          \n");
    printf("\t\t\t  2 按姓名查找          \n");
    printf("\t\t---------------------------------------\n");
    printf("\t\t\t请输入菜单选项1-2:");
}

Student *Ffind(Student *head)//查询函数
{
    int k=1;
    if(head) //判断
    {
        system("cls");
        findmenu();
        int judge;
        scanf("%d",&judge);

        Student *p1;
        p1=head;

        printf("\t\t\t  输入你想查找的人:");
        if(judge==1)
        {
            int num;
            scanf("%d",&num);

            while(p1->number!=num)
            {
                p1=p1->next;
                if(!p1)
                {
                    puts("此人不存在!\n");
                    k=0;
                    break;
                }
            }
        }
        else
        {
            char name[20];
            scanf("%s",&name);
            while(strcmp(name,p1->name))
            {
                p1=p1->next;
                if(!p1)
                {
                    puts("此人不存在!\n");
                    k=0;
                    break;
                }
            }
        }
        if(k)
        {
            printf("\n");
            printf("║    学号  ║    姓名  ║  年龄   ║    性别  ║     出生年月    ║║   地址    ║║    电话    ║║      邮箱     ║\n");
            printf("    %d\t     %s\t   %d\t    %s\t      %s\t       %s\t      %s\t     %s\n ",
                   p1->number,p1->name,p1->age,p1->sex,p1->birthday,p1->address,p1->phone,p1->email);
        }
    }
    else
    {
        k=0;
        printf("此文件为空,请先输入数据");
    }

    system("pause");
    if(k)
        return head;
    else
        return NULL;
}

Student *Find(Student *head)//查找函数(用于修改函数中)界面比Ffind函数简洁
{
    int k=1;
    if(head) //判断
    {
        printf("---请先查找要修改的人---\n");
        printf(">>>按学号查找请按1\t按姓名查找请按2\n");//选择根据名字还是根据学号查询
        int judge;
        scanf("%d",&judge);

        Student *p1;
        p1=head;

        printf("输入你想修改的人:");
        if(judge==1)
        {
            int num;
            scanf("%d",&num);
            while(head->number!=num)
            {
                head=head->next;
                if(!head)
                {
                    puts("此人不存在!\n");
                    k=0;
                    break;
                }
            }
        }
        else
        {
            char name[20];
            scanf("%s",&name);
            while(strcmp(name,head->name))
            {
                head=head->next;
                if(!head)
                {
                    puts("此人不存在!\n");
                    k=0;
                    break;
                }
            }
        }

    }
    else
    {
        k=0;
        puts("此文件为空!");
    }
    system("pause");
    if(k)
        return head;
    else
        return NULL;
}

void xiugaimenu()
{
    printf("\n\n\n");
    printf("\t\t\t☆☆学生信息修改☆☆\n");
    printf("\t\t---------------------------------------\n");
    printf("\t\t\t  1 修改学号          \n");
    printf("\t\t\t  2 修改姓名          \n");
    printf("\t\t\t  3 修改年龄          \n");
    printf("\t\t\t  4 修改性别          \n");
    printf("\t\t\t  5 修改生日          \n");
    printf("\t\t\t  6 修改地址          \n");
    printf("\t\t\t  7 修改电话          \n");
    printf("\t\t\t  8 修改邮箱          \n");
    printf("\t\t---------------------------------------\n");
    printf("\t\t\t请输入菜单选项1-8:");
}

Student *Change(Student *headI)//修改信息
{
    int n;
    Student *head=Find(headI);//由于之前已经定义过find函数,故此处不需要再搜索,直接调用find函数即可
    getchar();
    system("cls");
    xiugaimenu();
    if(head) //判断
    {
        scanf("%d",&n);
        switch(n)
        {
        case 1:
        {
            printf("\t\t\t 学号修改为:");
            scanf("%d",&head->number);
            printf("\t\t\t 修改成功!");//
            system("pause");
            break;
        }
        case 2:
        {
            printf("\t\t\t 姓名修改为:");
            scanf("%s",&head->name);
            printf("\t\t\t 修改成功!");
            system("pause");
            break;
        }
        case 3:
        {
            printf("\t\t\t 年龄修改为:");
            scanf("%d",&head->age);
            printf("\t\t\t 修改成功!");
            system("pause");
            break;
        }
        case 4:
        {
            printf("\t\t\t 性别修改为:");
            scanf("%s",&head->sex);
            printf("\t\t\t 修改成功!");
            system("pause");
            break;
        }
        case 5:
        {
            printf("\t\t\t 生日修改为:");
            scanf("%s",&head->birthday);
            printf("\t\t\t 修改成功!");
            break;
        }
        case 6:
        {
            printf("\t\t\t 地址修改为:");
            scanf("%s",&head->address);
            printf("\t\t\t 修改成功!");
            system("pause");
            break;
        }
        case 7:
        {
            printf("\t\t\t 电话修改为:");
            scanf("%s",&head->phone);
            printf("\t\t\t 修改成功!");
            break;
        }
        case 8:
        {
            printf("\t\t\t 邮箱修改为:");
            scanf("%s",&head->email);
            printf("\t\t\t 修改成功!");
            system("pause");
            break;
        }
        default:
            printf("选项错误!按任意键继续!");
            getchar();
            system("cls");
        }
        head=Sort(headI);
        Write(headI);
    }
    return headI;
}

void menu()//主菜单
{
    system("cls");//清空屏幕
    printf("\t -----------------------------------------------------\n");
    printf("\t                                                          \n");
    printf("\t    ☆☆☆     欢迎使用学生信息管理系统     ☆☆☆                 ");
    printf("\t                                                          \n");
    printf("\t -----------------------------------------------------\n");
    printf("\t          |      1 → 录入学生信息             |\n");
    printf("\t          |      2 → 浏览学生信息             |\n");
    printf("\t          |      3 → 查找学生信息             |\n");
    printf("\t          |      4 → 修改学生信息             |\n");
    printf("\t          |      5 → 添加学生信息             |\n");
    printf("\t          |      6 → 删除学生信息             |\n");
    printf("\t          |      7 → 退出管理系统             |\n");
    printf("\t -----------------------------------------------------\n");
    printf("\t\t\t\t\t\t");
    system("date/t");
    printf("\t\t\t\t\t\t   ");
    system("time/t");
    printf("\t请选择菜单选项1-7:");
}


//主函数
int main()
{
    system("title 学生管理系统");
    system("color F4");
    system("mode 130,100");
    menu();//初始化页面
    Student *head=NULL;//创建临时链表
    head=Read();//每次先从文件读出链表
    int n;
    while(1)
    {
        scanf("%d",&n);
        switch(n)
        {
        case 1:
            system("cls");
            head=Input();
            break;
        case 2:
            system("cls");
            Show(head);
            break;
        case 3:
            system("cls");
            Ffind(head);
            break;
        case 4:
            system("cls");
            head=Change(head);
            break;
        case 5:
            system("cls");
            head=Add(head);
            break;
        case 6:
            system("cls");
            head=Delete(head);
            break;
        case 7:
            printf("\n\t\t★★★感谢您的使用,期待下一次相遇★★★\n");
            exit(0);
            break;
        }
        menu();
    }
    return 0;
}

  • 61
    点赞
  • 340
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值