C语言程序设计实践——学生信息管理系统(动态数组、链表)【更新完成7.15】

从上周日(4.19)开始,每周日上午第一节便是C语言的实践课。本次实践课的第一个任务便是利用所学的知识,基于动态数组和链表知识设计一个学生信息管理系统。与做单独的一道题不同,设计整个系统就对各模块间的相互配合、人机交互内容等方面提出了更大的要求。
万事开头难,设计第一个程序注定是最困难的。但我能做的,便是紧跟老师的脚步,迈好第一步。加油,奥利给!
——2020.4.26

一个完整的学生信息管理系统要求完成以下功能:

  • 学生信息的录入(从键盘输入、从文件导入)
  • 学生信息的输出
  • 学生信息的查询(通过不同的查询方式)
  • 学生信息的删除
  • 输入错误的提示(一定的容错功能)
  • 实现方式链表化

一、本系统专用头文件 stu.h

为了防止重复定义变量、函数等,为整个系统定义一个新的头文件,在剩余的工程文件里只需要调用该头文件即可,省去很多麻烦。
头文件的内容就是所有工程文件会用到的变量和函数原型声明。

//stu.h
#ifndef STU_H_INCLUDED
#define STU_H_INCLUDED
#define LEN sizeof(struct Student)

struct Student//整个系统的核心:结构体数组
{
    int num;
    char name[10];
    char sex;
    int age;
    double score[3];
    double avg;//平均分
    double sum;//总分
    int position;//名次
};

//完成main函数中定义的变量在其他工程中的可用性
extern int n,i;
extern struct Student *p;

//其他工程中的函数原型声明
//hello.c
void Sayhello();
void Menu();
void SayGoodbye();

//output.c
void outputheader();
void output(struct Student *p);
void outputs(struct Student *p,int n);

//insert.c
void inputs(struct Student *p);
void addfromkeybroad();
void addhello();
//search.c
void searchhello();
int searchnum(struct Student *p,int n);
int searchname(struct Student *p,int n);
int searchscore(struct Student *p,int n);

//delete.c
void delhello();
void delnum(struct Student *p,int n);
void delname(struct Student *p,int n);
void delscore(struct Student *p,int n);

//sort.c
void sorthello();
void sortsumgrade(struct Student *p,int n);
void sortno(struct Student *p,int n);
void sortname(struct Student *p,int n);
void sortnumber(struct Student *p,int n);

//update.c
void newhello();
void newnum(struct Student *p,int n,int no);
void newname(struct Student *p,int n,int no);
void newsex(struct Student *p,int n,int no);
void newage(struct Student *p,int n,int no);
void newscore(struct Student *p,int n,int no,int cnt);

#endif // STU_H_INCLUDED

二、开始菜单 hello.c

程序开始时需要对程序内容进行简介,并进行可完成功能的显示以供使用者选择,在程序结束后需要有结束告别语。

hello.c
#include 
#include 
#include "stu.h"

void Sayhello()//开始的欢迎语
{
    printf("**********************************************\n");
    printf("***********本程序由某不知名人士开发***********\n");
    printf("***************技术支持:李瑞改***************\n");
    printf("*****************感谢您的使用*****************\n");
    printf("**********************************************\n");
}

void Menu()//功能菜单
{
    printf("请输入您想要进行的操作:\n");
    printf("1表示添加学生信息\n");
    printf("2表示修改学生信息\n");
    printf("3表示删除学生信息\n");
    printf("4表示查询学生信息\n");
    printf("5表示对学生信息进行排序\n");
    printf("6表示输出学生信息\n");
    printf("7表示清屏\n");
    printf("0表示退出系统\n");
}

void SayGoodbye()//结束告别语
{
    printf("朋友,有缘再见!\n");
}

三、功能1:学生信息的录入 insert.c

1.从键盘录入学生数据

//insert.c
#include 
#include 
#include "stu.h"

void inputs(struct Student *p)//输入函数
{
    printf("请输入学生的信息,格式如下:\n");//输入的提示信息
    printf("学号 姓名 性别 年龄 成绩1 成绩2 成绩3\n");
    //p->sum=0;
    //int i;
    scanf("%d %s %c %d %lf %lf %lf",&p->num,p->name,&p->sex,&p->age,&p->score[0],&p->score[1],&p->score[2]);
    p->sum=p->score[0]+p->score[1]+p->score[2];
    p->avg=p->sum/3.0;
}

void addfromkeybroad()//键盘输入函数
{
    int m;
    printf("请输入添加学生的人数\n");
    scanf("%d",&m);
    if(n==0){
        p=(struct Student *)malloc(m*LEN);
        if(p==NULL){
            printf("Memory Error!\n");
            exit(1);
        }
        for(i=0;i<m;i++)
            inputs(p+i);
        n=m;
    }
    else{
        p=(struct Student *)realloc(p,(n+m)*LEN);
        if(p==NULL){
            printf("Memory Error!\n");
            exit(1);
        }
        for(i=0;i<m;i++)
            inputs(p+n+i);
        n+=m;
    }
}

void addhello()//输入方式确认界面
{
    int rec1;
    printf("1表示从键盘添加学生信息\n");
    printf("2表示从文件添加学生信息\n");
    printf("0表示返回上一级菜单\n");
    scanf("%d",&rec1);
    if(rec1==0) return;
    switch(rec1){
    case 1:addfromkeybroad();
        break;
    case 2://from file
        break;
    }
}

四、功能2:学生信息的输出 output.c

将目前已有的学生信息全部输出。

//output.c
#include 
#include 
#include "stu.h"

void outputheader()//输出信息前先打印表头
{
    printf("学号 姓名 性别 年龄 成绩1 成绩2 成绩3 总成绩 平均成绩 名次\n");
}

void output(struct Student *p)//单个输出函数
{
    int i;
    outputheader();
    printf("%d %s %c %d ",p->num,p->name,p->sex,p->age);
    for(i=0;i<3;i++)
        printf("%.2lf ",p->score[i]);
    printf("%.2lf %.2lf %d\n",p->sum,p->avg,p->position);
}

void outputs(struct Student *p,int n)//多个输出函数
{
    if(n==0){//如果当前没有已存储的学生数据,需要报错
        printf("当前没有学生,请先添加学生信息!\n");
        return ;
    }
    int i;
    outputheader();
    for(i=0;i<n;i++,p++)
        output(p);
}

五、功能3:学生信息的查询 search.c

给定条件在已有信息中查询,若有满足条件的学生则输出。

//search.c
#include 
#include 
#include "stu.h"
#include 

void searchhello()//查询方式索引
{
    printf("查询信息:\n");
    printf("1表示根据学号查询信息\n");
    printf("2表示根据姓名查询信息\n");
    printf("3表示根据总成绩查询信息\n");
    int rec2;
    scanf("%d",&rec2);
    switch(rec2){
    case 1://学号
        searchnum(p,n);
        break;
    case 2://姓名
        searchname(p,n);
        break;
    case 3://总成绩
        searchscore(p,n);
        break;
    }
}

int searchnum(struct Student *p,int n)//根据学号查找学生
{
    printf("请输入查找的学号:\n");
    int snum,flag=0;
    struct Student *q;
    q=p;
    scanf("%d",&snum);
    for(int i=0;i<n;i++){
        if((q+i)->num==snum){
            flag=1;
            printf("已找到该学生,TA的信息为:\n");
            output(q+i);
            return i;
            break;
        }
    }
    if(flag==0){printf("未找到该学生,请检查后再试\n");return -1;}
}

int searchname(struct Student *p,int n)//根据学生姓名查找学生
{
    printf("请输入查找的姓名:\n");
    char sname[20];
    int flag=0;
    struct Student *q;
    q=p;
    scanf("%s",sname);
    for(int i=0;i<n;i++){
        if(strcmp((q+i)->name,sname)==0){
            flag=1;
            printf("已找到该学生,TA的信息为:\n");
            output(q+i);
            return i;
            break;
        }
    }
    if(flag==0){printf("未找到该学生,请检查后再试\n");return -1;}
}

int searchscore(struct Student *p,int n)//根据学生总成绩查找学生
{
    printf("请输入查找的总成绩:\n");
    int flag=0;
    double ssum;
    struct Student *q;
    q=p;
    scanf("%lf",&ssum);
    for(int i=0;i<n;i++){
        if((q+i)->sum==ssum){
            flag=1;
            printf("已找到该学生,TA的信息为:\n");
            output(q+i);
            return i;
            break;
        }
    }
    if(flag==0) {printf("未找到该学生,请检查后再试\n");return -1;}
}

六、功能4:学生信息的删除 delete.c

给定条件,如果有满足条件的学生则从系统中删除。

//delete.c
#include 
#include 
#include "stu.h"
#include 

void delhello()//删除方式索引
{
    int rec3;
    printf("删除信息:\n");
    printf("1表示根据学号删除信息\n");
    printf("2表示根据姓名删除信息\n");
    printf("3表示根据成绩删除信息\n");
    printf("0表示返回上一级菜单\n");
    scanf("%d",&rec3);
    if(rec3==0) return;
    switch(rec3){
        case 1://学号
            delnum(p,n);
            break;
        case 2://姓名
            delname(p,n);
            break;
        case 3://成绩
            delscore(p,n);
            break;
    }
}

void delnum(struct Student *p,int n)//根据学生学号删除学生
{
    printf("请输入想要删除的学生的学号:\n");
    int snum,flag=0,m;
    struct Student *q;
    q=p;
    scanf("%d",&snum);
    for(int i=0;i<n;i++){
        if((q+i)->num==snum){
            flag=1;
            printf("已找到该学生,TA的信息为:\n");
            output(q+i);
            printf("是否确定要删除?确定输入1,再想想输入0\n");
            int chose;
            scanf("%d",&chose);
            if(chose==1){
                for(m=i;m<n-1;m++){
                    *(q+m)=*(q+m+1);
                }
                n-=1;
            }
            else return;
            break;
        }
    }
    if(flag==0) printf("未找到该学生,请检查后再试\n");
}

void delname(struct Student *p,int n)//根据学生姓名删除学生
{
    printf("请输入要删除的学生的姓名:\n");
    char sname[20];
    int flag=0,m;
    struct Student *q;
    q=p;
    scanf("%s",sname);
    for(int i=0;i<n;i++){
        if(strcmp((q+i)->name,sname)==0){
            flag=1;
            printf("已找到该学生,TA的信息为:\n");
            output(q+i);
            printf("是否确定要删除?确定输入1,再想想输入0\n");
            int chose;
            scanf("%d",&chose);
            if(chose==1){
                for(m=i;m<n-1;m++){
                    *(q+m)=*(q+m+1);
                }
                n-=1;
            }
            else return;
            break;
        }
    }
    if(flag==0) printf("未找到该学生,请检查后再试\n");
}

void delscore(struct Student *p,int n)//根据学生总成绩删除学生
{
    printf("请输入要删除的学生的总成绩:\n");
    int flag=0,m;
    double ssum;
    struct Student *q;
    q=p;
    scanf("%lf",&ssum);
    for(int i=0;i<n;i++){
        if((q+i)->sum==ssum){
            flag=1;
            printf("已找到该学生,TA的信息为:\n");
            output(q+i);
            printf("是否确定要删除?确定输入1,再想想输入0\n");
            int chose;
            scanf("%d",&chose);
            if(chose==1){
                for(m=i;m<n-1;m++){
                    *(q+m)=*(q+m+1);
                }
                n-=1;
            }
            else return;
            break;
        }
    }
    if(flag==0) printf("未找到该学生,请检查后再试\n");
}

七、功能5:修改学生信息 update.c

先根据给定条件查找到需要被修改的学生,再选择修改该学生的某一信息。

在学生查询模块中,查找学生函数将返回学生在动态数组中的位置,可以在修改模块中直接调用,省去再次查询的麻烦。
//update.c
#include 
#include 
#include "stu.h"
#include 

void newhello()//修改学生信息索引
{
    printf("修改信息:\n");
    printf("请输入被修改学生的查询条件:\n");
    printf("1表示已知学号:\n");
    printf("2表示已知姓名:\n");
    printf("3表示已知总成绩:\n");
    printf("0表示返回上一级:\n");
    int t,no;
    scanf("%d",&t);
    switch(t){
        case 1:no=searchnum(p,n);break;//直接调用查询函数中返回的学生位置
        case 2:no=searchname(p,n);break;
        case 3:no=searchscore(p,n);break;
        case 0:break;
    }
    printf("1表示修改学号\n");
    printf("2表示修改姓名\n");
    printf("3表示修改年龄\n");
    printf("4表示修改性别\n");
    printf("5表示修改成绩1\n");
    printf("6表示修改成绩2\n");
    printf("7表示修改成绩3\n");
    printf("0表示返回上一级\n");
    int rec4;
    scanf("%d",&rec4);
    switch(rec4){
        case 1:newnum(p,n,no);break;
        case 2:newname(p,n,no);break;
        case 3:newage(p,n,no);break;
        case 4:newsex(p,n,no);break;
        case 5:newscore(p,n,no,0);break;
        case 6:newscore(p,n,no,1);break;
        case 7:newscore(p,n,no,2);break;
        case 0:break;
    }
}

void newnum(struct Student *p,int n,int no)//修改学号
{
    struct Student *q;
    q=p;
    printf("是否确定要修改?确定输入1,再想想输入0\n");
    int chose;
    scanf("%d",&chose);
    if(chose==1){
        int nnum;
        printf("请输入新的学号:\n");
        scanf("%d",&nnum);
        (q+no)->num=nnum;
    }
    else return;
}

void newname(struct Student *p,int n,int no)//修改姓名
{
    struct Student *q;
    q=p;
    printf("是否确定要修改?确定输入1,再想想输入0\n");
    int chose;
    scanf("%d",&chose);
    if(chose==1){
        char nname[20];
        printf("请输入新的姓名:\n");
        scanf("%s",nname);
        strcpy((q+no)->name,nname);
    }
    else return;
}

void newsex(struct Student *p,int n,int no)//修改性别
{
    struct Student *q;
    q=p;
    printf("是否确定要修改?确定输入1,再想想输入0\n");
    int chose;
    scanf("%d",&chose);
    if(chose==1){
        char nsex;
        printf("请输入新的性别:\n");
        scanf("%c",&nsex);
        (q+no)->sex=nsex;
    }
    else return;
}

void newage(struct Student *p,int n,int no)//修改年龄
{
    struct Student *q;
    q=p;
    printf("是否确定要修改?确定输入1,再想想输入0\n");
    int chose;
    scanf("%d",&chose);
    if(chose==1){
        int nage;
        printf("请输入新的年龄:\n");
        scanf("%d",&nage);
        (q+no)->age=nage;
    }
    else return;
}

void newscore(struct Student *p,int n,int no,int cnt)//修改成绩
{
    struct Student *q;
    q=p;
    printf("是否确定要修改?确定输入1,再想想输入0\n");
    int chose;
    scanf("%d",&chose);
    if(chose==1){
        double nscore;
        printf("请输入新的成绩:\n");
        scanf("%lf",&nscore);
        (q+no)->score[cnt]=nscore;
        (q+no)->sum=(q+no)->score[0]+(q+no)->score[1]+(q+no)->score[2];
        (q+no)->avg=(q+no)->sum/3.0;
    }
    else return;
}

八、功能6:学生信息的排序 sort.c

对所有学生信息按确定条件排序并输出。

//sort.c
#include 
#include 
#include "stu.h"
#include 


void sorthello()//学生排序索引
{
    int t;
    printf("请选择排序方式:\n");
    printf("1表示按照学号先后排名:\n");
    printf("2表示按照姓名先后排名:\n");
    printf("3表示按照总成绩排名:\n");
    printf("0表示返回上一级\n");
    scanf("%d",&t);
    switch(t)
    {
        case 1:sortno(p,n);break;
        case 2:sortname(p,n);break;
        case 3:sortsumgrade(p,n);break;
        case 0:break;
    }
}
void sortsumgrade(struct Student *p,int n)   //按照总成绩从大到小排名;
{
    struct Student flag,*q;
    int i,j;
    q=p;                                      //保存结构体的首地址;
    for(i=0;i<n;i++)                          //冒泡排序进行排名;
    {
        for(j=0;j<n-1;j++)
        {
            if((p+j)->sum<(p+j+1)->sum)
            {
                flag=*(p+j);                   //符合条件,交换数据;
                *(p+j)=*(p+j+1);
                *(p+j+1)=flag;
            }
        }
    }
    sortnumber(p,n);                          //给予编号;
}

void sortno(struct Student *p,int n)    //按照学号先后排名
{
    struct Student flag,*q;
    int i,j,t;
    q=p;                                  //保存结构体的首地址;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n-1;j++)
        {
            t=((p+j)->num<(p+j+1)->num);  //变量保存比较结果;
            if(t>0)
            {
                flag=*(p+j);                //符合条件,交换结构体类型数据;
                *(p+j)=*(p+j+1);
                *(p+j+1)=flag;
            }
        }
    }
    sortnumber(p,n);                        //给予编号;
}


void sortname(struct Student *p,int n)   // 按照姓名首字母排名
{
    struct Student flag,*q;
    int i,j,t;
    q=p;                                  //保存结构体的首地址;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n-1;j++)
        {
            t=strcmp((p+j)->name,(p+j+1)->name);
            if(t>0)
            {
                flag=*(p+j);              //交换数据;
                *(p+j)=*(p+j+1);
                *(p+j+1)=flag;
            }
        }
    }
    sortnumber(p,n);                     //给予编号;
}


void sortnumber(struct Student *p,int n)   //名次排序
{
    int i;
    for(i=1;i<=n;i++)                       //给予编号;
    {
        (p+i-1)->position=i;
    }
}

九、系统终端-main函数 main.c

在main函数中需要做的便是做最原始的客户端的操作,进行最初的数据接收与函数调用。

//main.c
#include 
#include 
#include "stu.h"
#include 

struct Student *p=NULL;
int n=0,i,com;

int main()
{
    Sayhello();
    while(1){
        Menu();
        if(scanf("%d",&com)!=1){
            printf("您的输入不正确,请重新输入,别瞎输!\n");
            fflush(stdin);
            continue;
        }
        if(com==0) break;
        switch(com){
        case 1://insert插入
            addhello();
            break;
        case 2://update更新
            newhello();
            break;
        case 3://delete删除
            delhello();
            break;
        case 4://search查找
            searchhello();
            break;
        case 5://sort排序
            sorthello();
            break;
        case 6://output输出
            outputs(p,n);
            break;
        case 7://clear清屏
            system("cls");
            break;
        }
    }
    SayGoodbye();
    return 0;
}

十、学生信息管理系统的链表化

将存储学生信息的载体变成单向链表,将整个系统重做,并添加了文件读写操作与排序时学生名次的维护。

#include 
#include 
#include 
#define LEN sizeof(struct Link_Node)
#define FILENAME "D:\\stu.dat"

typedef struct Student//学生结构体定义
{
    int no;
    char name[30];
    int grade;
    int mc;
}student;

typedef struct Link_Node//链表定义
{
    student Data;
    struct Link_Node * next;
}node,* Link_Pointer;

int SavedTag,n,i;
node * pHead=NULL;
char filename[100]=FILENAME;

Link_Pointer init()//链表的初始化
{
    node * pHead=(node *)malloc(LEN);
    if(pHead==NULL)
    {
        printf("memory error!\n");
        exit(1);
    }
    pHead->next=NULL;
    return pHead;
}

//主要函数的原型声明
//hello.c()
void Sayhello();
void Menu();
void SayGoodbye();

//insert.c()
void addhello();
int CreateStuLink(node *pHead,int n);
int CreateLinkFromFile(node *pHead,char * fn);

//output.c()
void output(node * pHead);
int save(node *pHead,char* fn);

//search.c()
void searchhello();
node * searchnum(node *pHead);
node * searchname(node *pHead);
node * searchscore(node *pHead);

//delete.c()
void delhello();
void delnum(node * pHead);
void delname(node * pHead);
void delscore(node * pHead);

//sort.c
int Length(node * pHead);
void sorthello();
void sortnum(node * pHead);
void sortname(node * pHead);
void sortscore(node * pHead);

//update.c
void newhello();
void newnum(node * pHead);
void newname(node * pHead);
void newscore(node * pHead);

void Sayhello()//欢迎菜单
{
    printf("**********************************************\n");
    printf("***********本程序由某不知名人士开发***********\n");
    printf("*****************感谢您的使用*****************\n");
    printf("**********************************************\n");
}

void Menu()//功能菜单
{
    printf("————————————————————————————————————————");
    printf("请输入您想要进行的操作:\n");
    printf("1表示添加学生信息\n");
    printf("2表示修改学生信息\n");
    printf("3表示删除学生信息\n");
    printf("4表示查询学生信息\n");
    printf("5表示对学生信息进行排序\n");
    printf("6表示输出学生信息\n");
    printf("7表示清屏\n");
    printf("8表示保存信息到文件\n");
    printf("0表示退出系统\n");
    printf("————————————————————————————————————————");
}

void SayGoodbye()//告别语
{
    printf("朋友,有缘再见!\n");
}

void addhello()//添加学生索引
{
    int rec1;
    printf("添加信息:\n");
    printf("1表示从键盘添加学生信息\n");
    printf("2表示从文件添加学生信息\n");
    printf("0表示返回上一级菜单\n");
    scanf("%d",&rec1);
    if(rec1==0) return;
    switch(rec1){
    case 1://from keyboard
        {
            printf("请输入学生人数:\n");
            while(scanf("%d",&n)==0)
            {
                printf("您的输入有错误,请检查后重新输入:\n");
                fflush(stdin);
                printf("请输入学生人数:\n");
            }
            CreateStuLink(pHead,n);
            SavedTag=1;
            printf("完成%d个学生信息的输入.\n",n);
        };
        break;
    case 2://from file
        {
            printf("是否从默认路径%s读取信息?0表示是,1表示否\n",FILENAME);
            int con;
            scanf("%d",&con);
            if(con==0){
                n=CreateLinkFromFile(pHead,FILENAME);
                SavedTag=1;
                printf("完成%d个学生信息的输入.\n",n);
            }
            else{
                printf("请输入读取信息的路径\n");
                scanf("%s",filename);
                n=CreateLinkFromFile(pHead,filename);
                SavedTag=1;
                printf("完成%d个学生信息的输入.\n",n);
            }
        }
        break;
    }
}

int CreateStuLink(node *pHead,int n)//从键盘添加学生信息链表
{
    int i;
    node * pNew,*pTail=pHead;
    for(i=0; i<n; i++)
    {
        pNew=(node *) malloc(LEN);
        if(pNew==NULL) return i;
        printf("请输入学生的信息:学号  姓名  成绩\n");
        scanf("%d%s%d",&pNew->Data.no,pNew->Data.name,&pNew->Data.grade);
        pNew->Data.mc=0;
        pNew->next=NULL;
        pTail->next=pNew;
        pTail=pNew;
    }
    return i;
}

int CreateLinkFromFile(node *pHead,char * fn)//从文件添加学生信息的链表
{
    FILE *fp;
    int n=0;
    node *pNew,*pTail=pHead;
    if((fp=fopen(fn,"rb"))==NULL )
    {
        printf("file open error!\n");
        exit(1);
    }
    pNew=(node *) malloc(LEN);
    fread(&pNew->Data,sizeof(struct Student),1,fp);
    while(feof(fp)==0)
    {
        n++;
        pNew->next=NULL;
        pTail->next=pNew;
        pTail=pNew;
        pNew=(node *) malloc(LEN);
        fread(&pNew->Data,sizeof(struct Student),1,fp);
    }
    free(pNew);
    fclose(fp);
    return n;
}


void output(node *pHead)//直接输出学生信息
{
    printf("学号 姓名 成绩 名次\n");
    pHead=pHead->next;
    while(pHead)
    {
        printf("%d %s %d %d\n",pHead->Data.no,pHead->Data.name,pHead->Data.grade,pHead->Data.mc);
        pHead=pHead->next;
    }
}

int save(node *pHead,char * fn)//将链表信息保存在文件中
{
    FILE *fp;
    pHead=pHead->next;
    if( (fp=fopen(fn,"wb")) ==NULL)
    {
        printf("文件打开不成功!\n");
        return -1;
    }
    while(pHead)
    {
        fwrite(&pHead->Data,sizeof(struct Student),1,fp);
        pHead=pHead->next;
    }
    fclose(fp);
    return 0;
}


void searchhello()//查找学生索引
{
    int rec2;
    printf("查询信息:\n");
    printf("1表示按照学号查询\n");
    printf("2表示按照姓名查询\n");
    printf("3表示按照成绩查询\n");
    printf("0表示返回上一级\n");
    scanf("%d",&rec2);
    switch(rec2){
        case 1:searchnum(pHead);
            break;
        case 2:searchname(pHead);
            break;
        case 3:searchscore(pHead);
            break;
        case 0:return;
    }
}

node * searchnum(node *pHead)
{
    int flag1=0,snum;
    printf("请输入该学生的学号:\n");
    scanf("%d",&snum);
    node *q=pHead;
    while(q!=NULL){
        if(q->Data.no==snum){
                flag1=1;
                printf("已找到该学生,TA的信息为:\n");
                printf("学号 姓名 成绩\n");
                printf("%d %s %d\n",q->Data.no,q->Data.name,q->Data.grade);
                return q;
                break;
        }
        q=q->next;
    }
    if(flag1==0){
        printf("未找到该学生,请检查后再试.\n");
        return NULL;
    }
}

node * searchname(node *pHead)
{
    int flag1=0;
    char sname[30];
    printf("请输入该学生的姓名:\n");
    scanf("%s",sname);
    node *q=pHead->next;
    while(q!=NULL){
        if(strcmp(q->Data.name,sname)==0){
                flag1=1;
                printf("已找到该学生,TA的信息为:\n");
                printf("学号 姓名 成绩\n");
                printf("%d %s %d\n",q->Data.no,q->Data.name,q->Data.grade);
                return q;
                break;
        }
        q=q->next;
    }
    if(flag1==0){
        printf("未找到该学生,请检查后再试.\n");
        return NULL;
    }
}

node * searchscore(node *pHead)
{
    int flag1=0,sscore;
    printf("请输入该学生的成绩:\n");
    scanf("%d",&sscore);
    node *q=pHead->next;
    while(q!=NULL){
        if(q->Data.grade==sscore){
                flag1=1;
                printf("已找到该学生,TA的信息为:\n");
                printf("学号 姓名 成绩\n");
                printf("%d %s %d\n",q->Data.no,q->Data.name,q->Data.grade);
                return q;
                break;
        }
        q=q->next;
    }
    if(flag1==0){
        printf("未找到该学生,请检查后再试.\n");
        return NULL;
    }
}

void delhello()
{
    int rec3;
    printf("删除信息:\n");
    printf("1表示根据学号删除信息\n");
    printf("2表示根据姓名删除信息\n");
    printf("3表示根据成绩删除信息\n");
    printf("0表示返回上一级菜单\n");
    scanf("%d",&rec3);
    if(rec3==0) return;
    switch(rec3){
        case 1://学号
            delnum(pHead);
            break;
        case 2://姓名
            delname(pHead);
            break;
        case 3://成绩
            delscore(pHead);
            break;
    }
}

void delnum(node * pHead)
{
    int flag=0,dsum;
    printf("请输入删除学生的学号:\n");
    scanf("%d",&dsum);
    node *q,*pLast;
    pLast=pHead;
    q=pLast->next;
    while(q!=NULL){
        if(q->Data.no==dsum){
            pLast->next=q->next;
            free(q);
            q=pLast;
            flag=1;
            n--;
        }
        pLast=q;
        q=pLast->next;
    }
    if(flag==0)
        printf("未找到该学生,请检查后再试.\n");
}

void delname(node * pHead)
{
    int flag=0;
    char dname[20];
    printf("请输入删除学生的姓名:\n");
    scanf("%s",dname);
    node *q,*pLast;
    pLast=pHead;
    q=pLast->next;
    while(q!=NULL){
        if(strcmp(q->Data.name,dname)==0){
            pLast->next=q->next;
            free(q);
            q=pLast;
            flag=1;
            n--;
        }
        pLast=q;
        q=pLast->next;
    }
    if(flag==0)
        printf("未找到该学生,请检查后再试.\n");
}

void delscore(node * pHead)
{
    int flag=0,dscore;
    printf("请输入删除学生的成绩:\n");
    scanf("%d",&dscore);
    node *q,*pLast;
    pLast=pHead;
    q=pLast->next;
    while(q!=NULL){
        if(q->Data.grade==dscore){
            pLast->next=q->next;
            free(q);
            q=pLast;
            flag=1;
            n--;
        }
        pLast=q;
        q=pLast->next;
    }
    if(flag==0)
        printf("未找到该学生,请检查后再试.\n");
}

void sorthello()
{
    int rec4;
    printf("信息排序:\n");
    printf("1表示按照学号排序\n");
    printf("2表示按照姓名排序\n");
    printf("3表示按照成绩排序\n");
    printf("0表示返回上一级\n");
    scanf("%d",&rec4);
    if(rec4==0) return;
    switch(rec4){
    case 1://学号
        sortnum(pHead);
        break;
    case 2://姓名
        sortname(pHead);
        break;
    case 3://成绩
        sortscore(pHead);
        break;
    }

}

int Length(node * pHead)
{
    int n;
    node * p=pHead->next;
    while(p!=NULL){
        n++;
        p=p->next;
    }
    return n;
}

void sortnum(node * pHead)
{
    int i,j;
    node *p,*pNext;
    student temp;
    for(i=0;i<n-1;i++){
        p=pHead->next;
        pNext=p->next;
        for(j=0;j<n-i-1;j++){
            if(p->Data.no>pNext->Data.no){
                temp=p->Data;
                p->Data=pNext->Data;
                pNext->Data=temp;
            }
            p=p->next;
            pNext=p->next;
        }
    }
    printf("排序成功%c!\n",1);
    output(pHead);
}

void sortname(node * pHead)
{
    int i,j;
    node *p,*pNext;
    student temp;
    for(i=0;i<n-1;i++){
        p=pHead->next;
        pNext=p->next;
        for(j=0;j<n-i-1;j++){
            if(strcmp(p->Data.name,pNext->Data.name)>0){
                temp=p->Data;
                p->Data=pNext->Data;
                pNext->Data=temp;
            }
            p=p->next;
            pNext=p->next;
        }
    }
    printf("排序成功%c!\n",1);
    output(pHead);
}

void sortscore(node * pHead)
{
    int i,j;
    node *p,*pNext,*pmc;
    student temp;
    for(i=0;i<n-1;i++){
        p=pHead->next;
        pNext=p->next;
        for(j=0;j<n-i-1;j++){
            if(p->Data.grade<pNext->Data.grade){
                temp=p->Data;
                p->Data=pNext->Data;
                pNext->Data=temp;
            }
            p=p->next;
            pNext=p->next;
        }
    }
    printf("排序成功%c!\n",1);
    pmc=pHead;
    int cnt=0;
    while(pmc!=NULL){
        pmc->Data.mc=cnt;
        cnt++;
        pmc=pmc->next;
    }
    output(pHead);
}

void newhello()
{
    printf("修改信息:\n");
    printf("请输入被修改学生的查询条件:\n");
    printf("1表示已知学号:\n");
    printf("2表示已知姓名:\n");
    printf("3表示已知总成绩:\n");
    printf("0表示返回上一级:\n");
    int t;
    scanf("%d",&t);
    if(t==0) return;
    switch(t)
    {
        case 1:newnum(pHead);break;
        case 2:newname(pHead);break;
        case 3:newscore(pHead);break;
    }
}

void newnum(node * pHead)
{
    node *p=searchnum(pHead);
    printf("请输入想要修改的信息:\n");
    printf("1表示修改学号\n");
    printf("2表示修改姓名\n");
    printf("3表示修改成绩\n");
    printf("0表示返回上一级\n");
    int x;
    scanf("%d",&x);
    if(x==0) return;
    switch(x){
        case 1:{
            printf("请输入修改后的学号:\n");
            int gnum;
            scanf("%d",&gnum);
            p->Data.no=gnum;
            sortnum(pHead);
            break;
        }
        case 2:{
            printf("请输入修改后的姓名:\n");
            char gname[20];
            scanf("%s",gname);
            strcpy(p->Data.name,gname);
            sortname(pHead);
            break;
        }
        case 3:{
            printf("请输入修改后的成绩:\n");
            int gscore;
            scanf("%d",&gscore);
            p->Data.grade=gscore;
            sortscore(pHead);
            break;
        }
    }
}

void newname(node * pHead)
{
    node *p=searchname(pHead);
    printf("请输入想要修改的信息:\n");
    printf("1表示修改学号\n");
    printf("2表示修改姓名\n");
    printf("3表示修改成绩\n");
    printf("0表示返回上一级\n");
    int x;
    scanf("%d",&x);
    if(x==0) return;
    switch(x){
        case 1:{
            printf("请输入修改后的学号:\n");
            int gnum;
            scanf("%d",&gnum);
            p->Data.no=gnum;
            sortnum(pHead);
            break;
        }
        case 2:{
            printf("请输入修改后的姓名:\n");
            char gname[20];
            scanf("%s",gname);
            strcpy(p->Data.name,gname);
            sortname(pHead);
            break;
        }
        case 3:{
            printf("请输入修改后的成绩:\n");
            int gscore;
            scanf("%d",&gscore);
            p->Data.grade=gscore;
            sortscore(pHead);
            break;
        }
    }
}

void newscore(node * pHead)
{
    node *p=searchscore(pHead);
    printf("请输入想要修改的信息:\n");
    printf("1表示修改学号\n");
    printf("2表示修改姓名\n");
    printf("3表示修改成绩\n");
    printf("0表示返回上一级\n");
    int x;
    scanf("%d",&x);
    if(x==0) return;
    switch(x){
        case 1:{
            printf("请输入修改后的学号:\n");
            int gnum;
            scanf("%d",&gnum);
            p->Data.no=gnum;
            sortnum(pHead);
            break;
        }
        case 2:{
            printf("请输入修改后的姓名:\n");
            char gname[20];
            scanf("%s",gname);
            strcpy(p->Data.name,gname);
            sortname(pHead);
            break;
        }
        case 3:{
            printf("请输入修改后的成绩:\n");
            int gscore;
            scanf("%d",&gscore);
            p->Data.grade=gscore;
            sortscore(pHead);
            break;
        }
    }
}

int main()
{
    Link_Pointer init();
    int com=0;
    pHead=init();
    SavedTag=1;
    Sayhello();
    while(1){
        Menu();
        if(scanf("%d",&com)!=1){
            printf("您的输入不正确,请重新输入,别瞎输!\n");
            fflush(stdin);
            continue;
        }
        if(com==0) break;
        switch(com){
        case 1://insert
            addhello();
            break;
        case 2://update
            newhello();
            break;
        case 3://delete
            delhello();
            break;
        case 4://find
            searchhello();
            break;
        case 5://sort
            sorthello();
            break;
        case 6://output
            output(pHead);
            break;
        case 7://clear
            system("cls");
            break;
        case 8://save
                printf("默认文件保存到%s,采用默认路径吗?如果采用输入0,否则输入1\n",filename);
                fflush(stdin);
                scanf("%d",&com);
                if(com==1)
                {
                    printf("请输入您要保存的路径名。\n");
                    scanf("%s",filename);
                }
                if(save(pHead,filename)==0)
                {
                    printf("保存信息成功!\n");
                    SavedTag=0;
                }else
                {
                    printf("保存信息不成功!\n");
                }
        }
    }
    SayGoodbye();
    return 0;
}

最后贴一个链表系统的直观设计流程图,希望能有所帮助

C语言程序设计实践——学生信息管理系统(动态数组、链表)【更新完成7.15】_第1张图片

————————————分隔线(上面是代码↑,下面是编程日志↓)——————————————
4.26 Sun
在老师的全程示范下完成了整个系统的大体框架设计和几个简单功能的实现,一个巨大的工程(误)就这样拉开了序幕。一切都从这里开始,开头还算顺利,希望之后的过程也能这样一帆风顺。
7.15 Wed
经过无数次的修改最终完版了,本来打算写成编程日志,结果因为中途任务繁忙没有时间,最后写成了实验报告。第一次写的大型系统,希望能给之后的编程带来指引与领导作用吧。

你可能感兴趣的:(日常,c语言)