基于文件的学生管理系统。

基于文件、链表的学生管理系统。将保存和读出分别封装成函数,调用更加方便。
欢迎大家一起交流。

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
typedef unsigned int u32;
typedef unsigned char u8;

typedef struct student//定义一个结构体当做数据域
{
    u32 id;
    u8 name[20];
    u8 sex;
    u32 old;
    float score;
}STUDENT;
typedef struct list_tag
{
    STUDENT stu;   //数据域
    struct list_tag *pnext;  //指针域

}LINK;
//保存表头指针
LINK *phead;
//保存新创建的节点指针
LINK *pnew;
//保存临时节点指针
LINK *ptmp;
LINK *next;
LINK *pdel;
LINK *pins;
FILE *fp;
enum MK
{
    add_tag=1,search_tag,del_tag,modify_tag,sort_tag,all_tag,ins_tag,out_tag
};

u32 count=0;
enum MK menu(void);
int creat(void);
int add(void);
void search(void);
void del(void);
int modify(void);
void sort(void);
void all(void);
void ins(void);
int save(void);
int read(void);
void out(void);
int main()
{


    if(creat()==0)
    {
        printf("创建失败\n");
        return 0;
    }
    read();
    while(1)
    {

        switch(menu())
        {
            case add_tag : add();break;
            case search_tag : search();break;
            case del_tag : del();break;
            case modify_tag : modify();break;
            case sort_tag : sort();break;
            case all_tag : all();break;
            case ins_tag : ins();break;
            case out_tag : out();save();return 0;
        }
    }

    return 0;
}
enum MK menu()
{
    enum MK num;
    printf("----------------------------------\n");
    printf("\t%d.增加学生信息\n",add_tag);
    printf("\t%d.查找学生信息\n",search_tag);
    printf("\t%d.删除学生信息\n",del_tag);
    printf("\t%d.修改学生信息\n",modify_tag);
    printf("\t%d.排序学生成绩\n",sort_tag);
    printf("\t%d.输出所有学生信息\n",all_tag);
    printf("\t%d.插入学生信息\n",ins_tag);
    printf("\t%d.退出系统\n",out_tag);
    printf("----------------------------------\n");
come:
    printf("请输入需要的功能前的编号以回车结尾\n");
    scanf("%d",&num);
    getchar();
    if(num<add_tag||num>out_tag)
    {
        printf("输入错误,请输入正确的编号\n");
        goto come;
    }
    return num;

}
int creat(void)
{
    phead=(LINK*)malloc(sizeof(LINK));//malloc函数有一个返回值是void*类型的必须强制转换为link*类型
    if(phead==NULL)
    {
        printf("创建失败\n");
        return 0;
    }
    printf("创建成功\n");
    printf("phead= %p\n", phead);
    memset(phead,0,sizeof(LINK));
    phead->pnext=NULL;//将单链表中第一个节点的指针域指针和数据域指针全部初始化
    return 1;
}
int add(void)
{
    u32 id=0;
    u32 flag=0;
    u8 ch;
add2:
    pnew=(LINK*)malloc(sizeof(LINK));
    if(pnew==NULL)
    {
        printf("创建失败\n");
        return 0;
    }
    printf("pnew=%p\n", pnew);
    memset(pnew,0,sizeof(LINK));
    pnew->pnext=NULL;//给新创建的节点指针域清空
    printf("输入要添加的学生的学号\n");
    scanf("%d", &id);
    getchar();
    ptmp=phead->pnext;//假设链表已经建立完毕,此时ptmp存放的是首节点的指针域的内容,也就是下一节点的头地址
    while(ptmp!=NULL)
    {
        if(ptmp->stu.id==id)//访问首节点指针域,所存放的下一节点的头地址里面的数据域里面的stu.id。
        {
            flag=1;
            break;
        }
        ptmp=ptmp->pnext;
    }
    if(flag==1)
    {
        printf("此学号已经被别人注册,请重新输入\n");
        free(pnew);//删除当前创建的节点。
        goto FFFF;
    }
    pnew->stu.id=id;//此时id的判断已经结束,可以进行后续的输入
    printf("请输入添加学生的姓名\n");
    scanf("%s", pnew->stu.name);
    getchar();
    printf("请输入添加学生的性别\n");
    scanf("%c", &pnew->stu.sex);
    getchar();
    printf("请输入添加学生的年龄\n");
    scanf("%d", &pnew->stu.old);
    printf("请输入添加学生的分数\n");
    scanf("%f", &pnew->stu.score);
    getchar();
    ptmp=phead;
    while(ptmp->pnext!=NULL)
    {
        ptmp=ptmp->pnext;
    }
    ptmp->pnext=pnew;//倒数第二个节点的,指针域存放新节点的头地址。这样新节点就变成了最后一个节点。
    count++;
FFFF:
    printf("是否继续添加(Y/N)\n");
	ch = getchar();
	getchar();
	if(ch == 'y' || ch == 'Y')
		goto add2;
	return 1;

}
void search(void)
{
    u32 id=0,flag=0;
    u8 ch;
come:
    printf("输入你想查询的学生的id\n");
    scanf("%d", &id);
    getchar();
    ptmp=phead->pnext;
    while(ptmp!=NULL)
    {
        if(ptmp->stu.id==id)
        {
            flag=1;
            break;
        }
        ptmp=ptmp->pnext;
    }
    if(flag==1)
    {
        printf("查找学生的信息如下:\n");
        printf("姓名:%s\n", ptmp->stu.name);
        printf("学号:%d\n", ptmp->stu.id);
        printf("性别:%c\n", ptmp->stu.sex);
        printf("年龄:%d\n", ptmp->stu.old);
        printf("分数:%f\n", ptmp->stu.score);
    }
    if(flag==0)
    {
        printf("查无此人\n");
    }
    printf("是否继续查询(Y/N)\n");
    scanf("%c", &ch);
    getchar();
    if(ch=='Y'||ch=='y')
    {
        goto come;
    }

}
void del(void)
{
    u32 flag=0,id;
    u8 ch,jc;
tw:
    printf("请输入需要删除的学生的id\n");
    scanf("%d", &id);
    getchar();
    ptmp=phead;
    while(ptmp->pnext!=NULL)
    {
        if(ptmp->pnext->stu.id==id)
        {
            flag=1;
            break;
        }
        ptmp=ptmp->pnext;
    }
    if(flag==1)
    {
        pdel=ptmp->pnext;
        printf("您要删除的学生信息如下:\n");
		printf("姓名:%s\n", pdel->stu.name);
        printf("学号:%d\n", pdel->stu.id);
        printf("性别:%c\n", pdel->stu.sex);
        printf("年龄:%d\n", pdel->stu.old);
        printf("分数:%f\n", pdel->stu.score);
		printf("请确认是否删除(Y/N)\n");
		scanf("%c", &ch);
		getchar();

		 if(ch=='Y'||ch=='y')
		{

			ptmp->pnext = pdel->pnext;//在删除之前需要将前后连起来
			free(pdel);//释放
			count--;
			printf("删除成功\n");
		}
    }

    else
    {
        printf("查无此人\n");
    }

        printf("是否继续删除(Y/N)\n");
        scanf("%c", &jc);
        getchar();
        if(jc == 'Y'|| jc == 'y')
        {
            goto tw;
        }

}
int modify(void)
{
    u32 id, flag=0,g;
    u32 a,b;//新的学号和年龄
    u8 c,ch;//新的性别
    u8 D[20];//新的名字
    float e;//新的分数
nice:
    printf("请输入您要修改的学生的学号\n");
    scanf("%d", &id);
    getchar();
   for(ptmp=phead->pnext;ptmp!=NULL;ptmp=ptmp->pnext)
   {
       if(ptmp->stu.id==id)
       {
        flag=1;
        break;

       }
   }
   if(flag==0)
   {
       printf("查无此人\n");
   }
       if(flag==1)
    {
        printf("请输入须要修改的学生信息前面的序号\n");
        printf("1 修改姓名    2 修改学号\n");
        printf("3 修改性别    4 修改年龄\n");
        printf("5 修改分数    6 退出\n");
        scanf("%d", &g);
        getchar();
        switch(g)
        {
        case 1:printf("请输入新姓名\n");
               scanf("%s", D);
               getchar();
               strcpy(ptmp->stu.name,D);
               break;
        case 2:printf("请输入新学号\n");
               scanf("%d", &a);
               getchar();
               ptmp->stu.id=a;
               break;
        case 3:printf("请输入心得性别\n");
               scanf("%c", &c);
               getchar();
               ptmp->stu.sex=c;
               break;
        case 4:printf("请输入新的年龄\n");
               scanf("%d", &b);
               getchar();
               ptmp->stu.old=b;
               break;
        case 5:printf("请输入新的分数\n");
               scanf("%f", &e);
               getchar();
               ptmp->stu.score=e;
               break;
        default:
            return 1;
        }
        printf("修改完成,是否继续修改(Y/N)\n");
        scanf("%c", &ch);
        getchar();
        if(ch=='Y'||ch=='y')
        {
            goto nice;
        }
        return 1;

    }
}
void sort(void)
{
    float type;
   for(ptmp=phead->pnext;ptmp!=NULL;ptmp=ptmp->pnext)
   {
       for(next=ptmp->pnext;next!=NULL;next=next->pnext)
       {
           if(next->stu.score>ptmp->stu.score)
           {
               type=next->stu.score;
               next->stu.score=ptmp->stu.score;
               ptmp->stu.score=type;

           }
       }
   }
   printf("所有学生成绩排序完毕\n");
}

void all(void)
{
    u32 i=0;
   for(ptmp=phead->pnext;ptmp!=NULL;ptmp=ptmp->pnext)
   {
        i++;
        printf("第%d名:\n", i);
        printf("姓名:%s\n", ptmp->stu.name);
        printf("学号:%d\n", ptmp->stu.id);
        printf("性别:%c\n", ptmp->stu.sex);
        printf("年龄:%d\n", ptmp->stu.old);
        printf("分数:%f\n", ptmp->stu.score);
   }
}
void ins()
{
    u32 id, flag=0,s,flag1=0;
    u8 ch;
sss:
    printf("请输入要插入节点的位置id\n");
    scanf("%d", &id);
    getchar();
    ptmp=phead->pnext;
    while(ptmp!=NULL)
    {
        if(ptmp->stu.id==id)
        {
            flag=1;
            pins=ptmp;
            break;
        }
        ptmp=ptmp->pnext;
    }
    if(flag==0)
    {
        printf("未找到插入位置是否重新查找(Y/y),或者直接插入表结尾(N/n)\n");
        ch=getchar();
        getchar();
        if(ch=='Y'||ch=='y')
        {
            goto ccc;
        }
        else
            add();
    }
    else
    {
    ccc:
        printf("请输入要插入的学生的学号\n");
        scanf("%d", &s);
        getchar();
        ptmp=phead->pnext;
        while(ptmp!=NULL)
        {
            if(ptmp->stu.id==s)
            {

                flag1=1;
                break;
            }
            ptmp=ptmp->pnext;
        }
        if(flag1==1)
        {
           printf("学号已经存在请重新输入\n");
           goto ccc;
        }
        else
        {
            pnew=(LINK*)malloc(sizeof(LINK));
            memset(pnew,0,sizeof(LINK));
            pnew->pnext=NULL;
            pnew->stu.id=s;
            printf("请输入添加学生的姓名\n");
            scanf("%s", pnew->stu.name);
            getchar();
            printf("请输入添加学生的性别\n");
            scanf("%c", &pnew->stu.sex);
            getchar();
            printf("请输入添加学生的年龄\n");
            scanf("%d", &pnew->stu.old);
            printf("请输入添加学生的分数\n");
            scanf("%f", &pnew->stu.score);
            getchar();
            pnew->pnext=pins->pnext;//把前一项指针域的值给新节点的指针域。这样新节点后面的一个节点就与新节点连在一起了。
            pins->pnext = pnew;//新节点前一个节点的指针域存上新节点的头指针。这样前一节点和新节点也连在一起了。
            count++;
        }

    }
    printf("是否继续插入(y/n)\n");
	if(getchar() == 'y')
        goto sss;


}

void out(void)
{
  printf("欢迎您下次使用,再见\n");
}
int save()
{
    u32 i;
    fp=fopen("管理系统.txt","w+");
    if(fp==NULL)
    {
        printf("创建失败\n");
        perror("fopen");
        return -1;
    }
    //fwrite(&count,sizeof(int),1,fp);
    if(fwrite(&count,sizeof(int),1,fp)==0)
    {
        perror("fwrite");
        printf("写入失败\n");
        fclose(fp);
        return -1;
    }
    ptmp=phead->pnext;
    for(i=0;i<count;i++)
    {
        printf("%d\n",i);
        fwrite(ptmp,sizeof(LINK),1,fp);
        ptmp=ptmp->pnext;
    }
    fclose(fp);
    printf("关闭成功\n");
}
int read()
{
    u32 i;
    fp=fopen("管理系统.txt","r");
       if(fp==NULL)
    {
        printf("创建失败\n");
        perror("fopen");
        return -1;
    }
    printf("创建成功\n");
    fread(&count,sizeof(int),1,fp);
    printf("count=%d", count);
    ptmp=phead;
    for(i=0;i<count;i++)
    {
    pnew=(LINK*)malloc(sizeof(LINK));//malloc函数有一个返回值是void*类型的必须强制转换为link*类型
    if(pnew==NULL)
    {
        printf("创建失败\n");
        return 0;
    }
    printf("创建成功\n");
    printf("pnew= %p\n", pnew);
    memset(pnew,0,sizeof(LINK));
    //将单链表中第一个节点的指针域指针和数据域指针全部初始化
    fread(pnew,sizeof(LINK),1,fp);
    pnew->pnext=NULL;
    ptmp->pnext=pnew;
    ptmp=ptmp->pnext;
    }
    fclose(fp);

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值