目录
昨天花了一天时间写的学生管理系统,主要用到链表和文件读写,功能都比较简单,流程图如下

定义学生结构体,初始化节点,如果文本中有内容,先要把文本中的内容读取到链表中
- #include "stdafx.h"
- #include
- #include
- #include
-
- 定义一个学生类型
- typedef struct Student
- {
- char ID[16];//学号
- char name[20];//姓名
- char sex[6];//性别
- int scoreCh;//语文成绩
- int scoreMa;//数学成绩
- int scoreEn;//外语成绩
- struct Student*pNext;//下一个学生的指针
- }Stu,*pStu;
-
- /************************************************************************/
- /*初始化*/
- /************************************************************************/
- pStu pHeader;
- pStu pTail;
- void initStu(char* path)
- {
- FILE*file;
- pHeader=(pStu)malloc(sizeof(Stu));
-
- if (pHeader==NULL)
- {
- printf("分配失败");
- }
- // 初始化头节点
- pTail=pHeader;
- pTail->pNext=NULL;
- //打开文件
- file=fopen(path,"r");
- if (file==NULL)
- {
- printf("打开文件失败!");
- return;
- }
- while(1)
- {
- pStu pNew=(pStu)malloc(sizeof(Stu));
- //scanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF
- //文件中没有内容了则释放刚刚给它分配的空间
- if (fscanf(file,"%s %s %s %d %d %d",&(pNew->ID),&(pNew->name),&(pNew->sex),&(pNew->scoreCh),&(pNew->scoreMa),&(pNew->scoreEn))==EOF)
- {
- free(pNew);
- pNew=NULL;
- break;
- }
- pNew->pNext=NULL;
- //将当前结点和新建的链接起来
- pTail->pNext=pNew;
- //调整当前结点为新结点
- pTail=pNew;
-
-
- }
- fclose(file);
-
-
-
- }

设置界面功能,用switch case,一个case对应一个功能.
- /************************************************************************/
- /*主界面*/
- /************************************************************************/
- void interface(char* path)
- {
- int c;
- while(1)
- {
- system("cls");
- printf(" ╪╪╪╪╪╪╧╧╧╧╧╧╧╧╪╪╪╪╪╪\n");
- printf("╔═══╧╧ 学生管理系统 ╧╧═══╗\n");
- printf("║※1.添加学生信息 ║\n");
- printf("║※2.查找学生信息 ║\n");
- printf("║※3.学生成绩排序 ║\n");
- printf("║※4.删除学生信息 ║\n");
- printf("║※5.修改学生信息 ║\n");
- printf("║※6.展示学生信息 ║\n");
- printf("║※0.退出程序 ║\n");
- printf("╚═════════════════╝\n");
- system("color 0A");
- scanf("%d",&c);
- getchar();
- switch(c)
- {
- case 1:
- {
- StudentAdd(path);
- break;
- }
- case 2:
- {
- StudentSearch();
- break;
- }
- case 3:
- {
- sort();
- break;
- }
- case 4:
- {
- delStu(path);
- break;
- }
- case 5:
- {
- alterStu(path);
- break;
- }
- case 6:
- {
- bianli(pHeader);
- break;
- }
- case 0:
- {
- exit(0);
- break;
- }
- default:
- {
- printf("Error!\n");
- }
-
- }
- system("pause");
- }
- }
- int main(int argc, char* argv[])
- {
- //获取运行目录
- char infoPath[100];
- GetCurrentDirectory(100,infoPath);
- strcat(infoPath,"\\stuinfo.txt");
- /*printf("%s",infoPath);*/
- initStu(infoPath);
- interface(infoPath);
- return 0;
- }
首先展示一下功能


添加学生信息要注意学号不能重复,所以要写个检查学号是否重复的功能
因为考虑到可能一次要输入多个学生信息,所以用了循环输入,输入#可以退出
特别注意,scanf多次输入要考虑scanf缓存的问题,一定要清除scanf缓存,不然数据可能错乱.
- //清除scanf缓存
- void safe_flush(FILE *fp)
- {
- int ch;
- while( (ch = fgetc(fp)) != EOF && ch != '\n' );
- }
-
- //写入文件
- void StudentWrite(char* infoPath,Student a)
- {
- FILE*fp;
-
- fp=fopen(infoPath,"a");
- if (fp==NULL)
- {
- printf("fopen error\n");
- }
- fprintf(fp,"%s %s %s %d %d %d\n",a.ID,a.name,a.sex,a.scoreCh,a.scoreMa,a.scoreEn);
- fclose(fp);
-
- }
- /*判断学号是否重复*/
- //1为重复 0为不重复
- int checkAdd(char* id)
- {
-
- pStu stu=pHeader->pNext;
- while(stu!=NULL)
- {
-
- if (strcmp(stu->ID,id)==0)
- {
- return 1;
- }
- stu=stu->pNext;
- }
- return 0;
-
- }
-
- /************************************************************************/
- /*添加学生信息*/
- /************************************************************************/
- void StudentAdd(char* path)
- {
- Student ss;
- system("cls");
- system("color 0D");
- printf("-------------------------------\n");
- printf("\t欢迎来到学生管理系统\t\n");
- printf("\t\t添加学生信息\n");
- printf("-------------------------------\n");
-
- while(1)
- {
-
- printf("请依次输入学生ID 姓名 性别 语文 数学 外语成绩,如果想结束输入,请按#退出\n");
- scanf("%s",ss.ID);
-
- if (!strcmp(ss.ID,"#"))
- {
- break;
- }
- if (checkAdd(ss.ID)==1)
- {
- printf("学生ID重复,不能添加!\n");
- safe_flush(stdin);//清除scanf缓存
- continue;
- }
-
- scanf("%s %s %d %d %d",ss.name,ss.sex,&ss.scoreCh,&ss.scoreMa,&ss.scoreEn);
- pStu pN=(pStu)malloc(sizeof(Stu));
- pN->pNext=NULL;
- //给新节点赋值
- strcpy(pN->ID,ss.ID);
- strcpy(pN->name,ss.name);
- strcpy(pN->sex,ss.sex);
- pN->scoreCh=ss.scoreCh;
- pN->scoreMa=ss.scoreMa;
- pN->scoreEn=ss.scoreEn;
-
- pTail->pNext=pN;
- pTail=pN;
-
- StudentWrite(path,ss);
-
-
- }
-
-
- }


查询很简单,下面上代码,检查学号这个功能光查找学生信息是不需要位置的,但为了兼顾删除和修改所以用到了位置
注意,(*pos)++一定要加括号,后面的++运算优先级比较高,我就是被这个小问题困扰了好大一会儿,还不知道哪里错了,大家千万别像我一样犯低级错误.
- /************************************************************************/
- /*查找学生信息*/
- /************************************************************************/
- pStu checkXuehao(char*x,int* pos)
- {
- pStu px=pHeader->pNext;
- *pos=-1;
- while(px!=NULL)
- {
- (*pos)++;
- if (strcmp(x,px->ID)==0)
- {
- return px;
- }
- px=px->pNext;
-
- }
-
- return NULL;
- }
- void StudentSearch()
- {
- system("cls");
- system("color 0C");
- printf("-------------------------------\n");
- printf("\t欢迎来到学生管理系统\t\n");
- printf("\t\t查找学生信息\n");
- printf("-------------------------------\n");
- char ID[16];
- printf("请输入您要查询的学生学号\n");
- scanf("%s",ID);
- int value;
- pStu s=checkXuehao(ID,&value);
- if (s==NULL)
- {
- printf("您输入的学号不存在\n");
- }
- else
- {
- printf("您查询的结果如下:\n");
- printf("%8s%8s%8s%8s%8s%8s\n","学号","姓名","性别","语文","数学","外语");
- printf("%8s%8s%8s%8d%8d%8d\n",s->ID,s->name,s->sex,s->scoreCh,s->scoreMa,s->scoreEn);
- }
-
- }

- /************************************************************************/
- /*展示学生信息*/
- /************************************************************************/
- void bianli(pStu stu)
- {
- system("cls");
- system("color 0E");
- printf("-------------------------------\n");
- printf("\t欢迎来到学生管理系统\t\n");
- printf("\t\t展示学生信息\n");
- printf("-------------------------------\n");
- pStu px=pHeader->pNext;
- printf("%8s%8s%8s%8s%8s%8s%8s\n","学号","姓名","性别","语文","数学","外语","总成绩");
- while(px!=NULL)
- {
- printf("%8s%8s%8s%8d%8d%8d%8d\n",px->ID,px->name,px->sex,px->scoreCh,px->scoreMa,px->scoreEn,px->scoreCh+px->scoreMa+px->scoreEn);
- px=px->pNext;
-
- }
-
- }
先用冒泡进行排序,然后再调用展示学生信息


上面这两张截图就是按总成绩排序打印的
- /************************************************************************/
- /*学生成绩排序*/
- /************************************************************************/
- void paixuCh(pStu pHeader,int c)
- {
- pStu p,p1,t=pHeader;
-
- for (p=pHeader->pNext;p!=NULL;p=p->pNext)
- {
- for (p1=p->pNext;p1!=NULL;p1=p1->pNext)
- {
- if (c==1)
- {
- if ((p->scoreCh)<(p1->scoreCh))
- {
- //复制内存
- //交换内存数据,不换指针,只需要将除pNext指针外的结构体数据拷贝交换即可
- MoveMemory(t,p,sizeof(Stu) - 4);
- MoveMemory(p,p1,sizeof(Stu) - 4);
- MoveMemory(p1,t,sizeof(Stu) - 4);
-
- }
- }
- else if (c==2)
- {
- if (p->scoreMa
scoreMa) - {
- MoveMemory(t,p,sizeof(Stu) - 4);
- MoveMemory(p,p1,sizeof(Stu) - 4);
- MoveMemory(p1,t,sizeof(Stu) - 4);
- }
- }
- else if (c==3)
- {
- if (p->scoreEn
scoreEn) - {
- MoveMemory(t,p,sizeof(Stu) - 4);
- MoveMemory(p,p1,sizeof(Stu) - 4);
- MoveMemory(p1,t,sizeof(Stu) - 4);
- }
- }
- else if(c==4)
- {
- if ((p->scoreCh+p->scoreMa+p->scoreEn)<(p1->scoreCh+p1->scoreMa+p1->scoreEn))
- {
- MoveMemory(t,p,sizeof(Stu) - 4);
- MoveMemory(p,p1,sizeof(Stu) - 4);
- MoveMemory(p1,t,sizeof(Stu) - 4);
-
- }
- }
-
-
- }
- }
-
- }
- void sort()
- {
- int c;
- system("cls");
- system("color 0B");
- printf("-------------------------------\n");
- printf("\t欢迎来到学生管理系统\t\n");
- printf("\t\t学生成绩排序\n");
- printf("-------------------------------\n");
- printf("*******************\n");
- printf("1.按语文成绩降序\n");
- printf("2.按数学成绩降序\n");
- printf("3.按外语成绩降序\n");
- printf("4.按总成绩降序\n");
- printf("*******************\n");
- scanf("%d",&c);
- switch(c)
- {
- case 1:
- {
- paixuCh(pHeader,c);
- bianli(pHeader);
- break;
-
- }
- case 2:
- {
- paixuCh(pHeader,c);
- bianli(pHeader);
- break;
-
- }
- case 3:
- {
- paixuCh(pHeader,c);
- bianli(pHeader);
- break;
-
- }
- case 4:
- {
- paixuCh(pHeader,c);
- bianli(pHeader);
- break;
-
- }
- default:
- {
- printf("Error!\n");
- }
- }
-
- }

删除要找到位置,方法以前单向链表那篇文章已经讲过了,这里就不多赘述了
- /************************************************************************/
- /*删除学生信息*/
- /************************************************************************/
- void rewrite(char* infoPath,pStu pHeader)
- {
- FILE*fp;
- pStu rep=pHeader->pNext;
-
- fp=fopen(infoPath,"w");
- if (fp==NULL)
- {
- printf("fopen error\n");
- }
- while(rep!=NULL)
- {
- fprintf(fp,"%s %s %s %d %d %d\n",rep->ID,rep->name,rep->sex,rep->scoreCh,rep->scoreMa,rep->scoreEn);
- rep=rep->pNext;
- }
-
- fclose(fp);
-
- }
- void delStu(char* path)
- {
- system("cls");
- system("color 0B");
- printf("-------------------------------\n");
- printf("\t欢迎来到学生管理系统\t\n");
- printf("\t\t删除学生信息\n");
- printf("-------------------------------\n");
- char ID[16];
- char a;
- printf("请输入您要删除的学生学号\n");
- scanf("%s",ID);
- int pos;
- int i=0;
- pStu s=checkXuehao(ID,&pos);
- pStu d=pHeader->pNext;
- if (s==NULL)
- {
- printf("您输入的学号不存在\n");
- }
- else
- {
- printf("您要删除的学生信息如下:\n");
- printf("%8s%8s%8s%8s%8s%8s\n","学号","姓名","性别","语文","数学","外语");
- printf("%8s%8s%8s%8d%8d%8d\n",s->ID,s->name,s->sex,s->scoreCh,s->scoreMa,s->scoreEn);
- printf("请问确定要删除吗?y/n\n");
- safe_flush(stdin);
- scanf("%c",&a);
- if (a=='n')
- {
- return;
- }
- else if (a=='y')
- {
- while (d!=NULL && i
1) - {
- i++;
- d=d->pNext;
- }
- /*printf("i%d pos%d\n",i,pos);*/
-
- d->pNext=d->pNext->pNext;
- free(s);
- s=NULL;
- rewrite(path,pHeader);
- printf("删除成功!\n");
- }
- else
- {
- printf("Error!/n");
-
- }
- }
- }
修改也是要找到位置,然后重新写入时写到要修改的位置时把数据换成新输入的数据.

- /************************************************************************/
- /*修改学生信息*/
- /************************************************************************/
- void alterwrite(char* infoPath,pStu pHeader,int* pos)
- {
- FILE*fp;
- pStu rep;
- Stu ss;
- int i=-1;
- printf("请依次输入学生ID 姓名 性别 语文 数学 外语成绩\n");
- scanf("%s %s %s %d %d %d",ss.ID,ss.name,ss.sex,&ss.scoreCh,&ss.scoreMa,&ss.scoreEn);
-
- fp=fopen(infoPath,"w");
- if (fp==NULL)
- {
- printf("fopen error\n");
- }
- rep=pHeader->pNext;
- while (rep!=NULL)
- {
- i++;
- if (i==(*pos))
- {
- strcpy(rep->ID,ss.ID);
- strcpy(rep->name,ss.name);
- strcpy(rep->sex,ss.sex);
- rep->scoreCh=ss.scoreCh;
- rep->scoreMa=ss.scoreMa;
- rep->scoreEn=ss.scoreEn;
- }
- fprintf(fp,"%s %s %s %d %d %d\n",rep->ID,rep->name,rep->sex,rep->scoreCh,rep->scoreMa,rep->scoreEn);
- rep=rep->pNext;
-
- }
-
- fclose(fp);
-
- }
- void alterStu(char* path)
- {
- system("cls");
- system("color 0D");
- printf("-------------------------------\n");
- printf("\t欢迎来到学生管理系统\t\n");
- printf("\t\t修改学生信息\n");
- printf("-------------------------------\n");
- char ID[16];
- char a;
- printf("请输入您要修改的学生学号\n");
- scanf("%s",ID);
- int pos=0;
- int i=0;
-
- pStu s=checkXuehao(ID,&pos);
- pStu d=pHeader;
-
- if (s==NULL)
- {
- printf("您输入的学号不存在\n");
- }
- else
- {
- printf("您要修改的学生信息如下:\n");
- printf("%8s%8s%8s%8s%8s%8s\n","学号","姓名","性别","语文","数学","外语");
- printf("%8s%8s%8s%8d%8d%8d\n",s->ID,s->name,s->sex,s->scoreCh,s->scoreMa,s->scoreEn);
- printf("请问确定要修改吗?y/n\n");
- /*printf("pos:%d\n",pos);*/
- safe_flush(stdin);
- scanf("%c",&a);
- if (a=='n')
- {
- return;
- }
- else if (a=='y')
- {
- alterwrite(path,pHeader,&pos);
- printf("修改成功!\n");
- }
- else
- {
- printf("Error!/n");
-
- }
- }
-
- }
今天的文章就到这里了,如果有任何不明白的地方欢迎与我交流,我必定知无不言。这篇文章也花了一定的心血,喜欢的小伙伴可以点赞关注哦。感激不尽!