定义一个包含学生信息(学号,姓名,性别,专业,语数外成绩,平均分,成绩排名)的链表,使其具有如下功能:
根据指定学生个数,逐个输入学生信息,并检查学号是否重复,成绩范围是否合理;
根据学号删除指定学生信息;
根据学号更改指定学生信息;
根据姓名或者学号进行查找,返回此学生的信息;
逐个输出所有学生的信息;
查询每门科目最高成绩;
对学生的成绩进行排序;
查询某个专业所有人的信息;
文件的保存和输出
建立索引文件,存入学号和姓名
话不多说,直接上代码!
#include<iostream> #include <malloc.h> #include<fstream> #include <stdlib.h> #include <string> #include <string.h> #include <conio.h> using namespace std; #define Maxsize 100 //学生成绩表结构体 typedef struct stu { int num; //学号 char name[10]; //姓名 char sex[4]; //性别 char subject[20]; //专业学科 int Math; //数学 int Chinese; //语文 int English; //英语 double avg; //成绩平均分 int rank; //总分排名 struct stu* next; //指向后续节点 }STU; //单链表节点类型 typedef struct Index { int no; int offset; char name[20]; }; STU* Head=NULL; //定义一个指针 STU* End = NULL; //尾结点 void CreatList() //创建头结点和尾结点 { Head = (struct stu*)malloc(sizeof(struct stu)); Head->next = NULL; STU* End = Head; } void menu(){ //菜单项 cout<<"\t\t***************************************"<<endl; cout<<"\t\t** 欢迎来到学生管理系统 **"<<endl; cout<<"\t\t** 1.添加学生信息 **"<<endl; cout<<"\t\t** 2.删除学生信息 **"<<endl; cout<<"\t\t** 3.修改学生信息 **"<<endl; cout<<"\t\t** 4.查询学生信息 **"<<endl; cout<<"\t\t** 5.输出学生信息 **"<<endl; cout<<"\t\t** 6.按成绩排名 **"<<endl; cout<<"\t\t** 7.查询专业所有学生 **"<<endl; cout<<"\t\t** 8.查询单科最高 **"<<endl; cout<<"\t\t** 9.文件管理系统 **"<<endl; cout<<"\t\t***************************************"<<endl; cout<<"请选择功能 输入序号:<1--9>: "; } //添加学生成绩信息 void AddStudent() { int n, i; cout<<"请输入您要添加的学生人数:"; cin>>n; for (i = 0; i<n; i++) { struct stu* pNew = (struct stu*)malloc(sizeof(struct stu)); pNew->next = NULL; cout<<"\n 要添加的第"<<i+1<<"个学生的信息如下:"<<endl; cout<<"\n请输入第"<<i+1<<"个学生学号: "; cin>>pNew->num; //检查是否已经添加过该学生,即检查学号是否重复 STU* temp = Head->next; while (temp != NULL) { if (temp->num == pNew->num) { cout<<"\n 学号重复,请重新输入!"<<endl; cout<<"\n请重新输入第"<<i<<"个学生学号: "; cin>>pNew->num; temp = Head->next; //重新遍历检查学号 continue; } else temp = temp->next; } cout<<"请输入第"<<i+1<<"个学生姓名: "; cin>>pNew->name; cout<<"请输入第"<<i+1<<"个学生性别: "; cin>>pNew->sex; cout<<"请输入第"<<i+1<<"个学生专业: "; cin>>pNew->subject; cout<<"请输入第"<<i+1<<"个学生数学成绩: "; cin>>pNew->Math; while (1) { if ((pNew->Math)< 0 || (pNew->Math > 100)) //检查成绩范围是否合理 { cout<<"\n 输入成绩有误,请检查!\n"; cout<<"请重新输入第"<<i+1<<"个学生数学成绩: "; cin>>pNew->Math; } else break; } cout<<"请输入第"<<i+1<<"个学生语文成绩: "; cin>>pNew->Chinese; while (1) { if ((pNew->Chinese)< 0 || (pNew->Chinese > 100)) { cout<<"\n 输入成绩有误,请检查!\n"; cout<<"请重新输入第"<<i+1<<"个学生语文成绩: "; cin>>pNew->Chinese; } else break; } cout<<"请输入第"<<i+1<<"个学生英语成绩: "; cin>>pNew->English; while (1) { if ((pNew->English)< 0 || (pNew->English) > 100) { cout<<"\n 输入成绩有误,请检查!\n"; cout<<"请重新输入第"<<i+1<<"个学生英语成绩: "; cin>>pNew->English; } else break; } //按学号排序,边添加边排序; if (Head->next == NULL) { Head->next = pNew; //作为首元素 End = Head->next; } else { if (pNew->num > End->num) { End->next = pNew; End = End->next; } else { STU* p1 = Head->next; if (pNew->num > p1->num) //链表中已经至少存在2个成员(至少存在首和尾); { STU* p2 = p1->next; while (1) { if ((pNew->num > p1->num) && (pNew->num < p2->num)) { pNew->next = p2; p1->next = pNew; break; } else //pNew->num > p2->num的情况 { p1 = p1->next; p2 = p2->next; } } } else //pNew->num < p1->num { pNew->next = p1; Head->next = pNew; } } } } cout<<"\n 学生信息全部添加完成!\n"; } //通过前驱结点删除学生成绩信息 void DeleteStudent() { int num1; cout<<"\n请输入您要删除的学生的学号:"; cin>>num1; STU* pre =Head; //表中没有数据时,pre为空; while (1) { if (pre->next && (pre->next->num == num1)) { STU* q = pre->next; //保存该节点信息 pre->next = pre->next->next; //断开pre->next节点 cout<<"\n 删除操作成功!\n"; cout<<"\n 已删除的学生成绩信息如下!\n\n"; cout<<"\t学号\t姓名\t性别\t专业\t\t数学\t语文\t英语\t\n\n"; cout<<"\t"<<q->num<<"\t"<<q->name<<"\t"<<q->sex<<"\t"<<q->subject<<"\t\t"<<q->Math <<"\t"<<q->Chinese<<"\t"<<q->English; free(q); return; } else { if (pre->next != NULL) pre = pre->next; else { cout<<"\n 信息删除失败!\n"; return; } } } } //更改学生成绩信息 void AlterStudent() { int num1; printf("\n请输入您要更改学生的学号:"); cin>>num1; STU* change = Head->next; while (change && (change->num != num1)) change = change->next; if (change) { cout<<"更改后的学号:"; cin>>change->num; cout<<"更改后的姓名: "; cin>> change->name; cout<<"更改后的性别: "; cin>>change->sex; cout<<"更改后的专业: "; cin>> change->subject; cout<<"更改后的数学成绩: "; cin>>change->Math; cout<<"更改后的语文成绩: "; cin>>change->Chinese; cout<<"更改后的英语成绩: "; cin>>change->English; cout<<"\n 学生信息已经更改完毕!!!\n"; } else cout<<"\n 学生信息不存在,无法更改!!!\n"; } //查询学生成绩信息 void SeekStudent() { while (1) { cout<<"\n请选择查询方式 按学号:1 按姓名:2: "; int k; cin>>k; switch (k) { case 1: { int num2; cout<<"\n请输入您要查找学生的学号:"; cin>>num2; STU* find = Head->next; while (find && (find->num != num2)) find = find->next; if (find) { cout<<"\n查询学生信息如下:\n\n"; cout<<"\t学号\t姓名\t性别\t专业\t\t数学\t语文\t英语\n\n"; cout<<"\t"<<find->num<<"\t"<<find->name<<"\t"<<find->sex<<"\t"<<find->subject<<"\t\t"<<find->Math <<"\t"<<find->Chinese<<"\t"<<find->English; } else cout<<"\n\n 没有查询到该学生信息!!!\n"; return; } case 2: { cout<<"\n请输入您要查找学生的姓名:"; char name1[20]; cin>>name1; STU* find = Head->next; while (find && (strcmp(find->name, name1) != 0)) find = find->next; if (find) { cout<<"\n查询学生信息如下:\n\n"; cout<<"\t学号\t姓名\t性别\t专业\t\t数学\t语文\t英语\n\n"; cout<<"\t"<<find->num<<"\t"<<find->name<<"\t"<<find->sex<<"\t"<<find->subject<<"\t\t"<<find->Math <<"\t"<<find->Chinese<<"\t"<<find->English; } else cout<<"\n 没有查询到该学生信息!!!\n"; return; } default: { cout<<"\n查询方式错误! 请重新选择查询方式\n"; break; } } } } //输出全部学生信息 void DisplayAll() { STU* p = Head->next; int len = 0; int SX = 0; int YW = 0; int YY = 0; double sum=0; double avg=0; cout<<"\n 全部学生成绩信息如下!\n\n"; cout<<"\t学号\t姓名\t性别\t专业\t\t数学\t语文\t英语\t平均分\n\n"; while (p!= NULL) { sum = p->Math + p->Chinese + p->English; avg=sum/3; p->avg=avg; cout<<"\t"<<p->num<<"\t"<<p->name<<"\t"<<p->sex<<"\t"<<p->subject<<"\t\t"<<p->Math <<"\t"<<p->Chinese<<"\t"<<p->English<<"\t"<<p->avg<<endl; SX = SX + p->Math; YW = YW + p->Chinese; YY = YY + p->English; p = p->next; //指针后移 len++; if (p == NULL) { cout<<"\n\n 成绩系统含学生总人数为:"<<len<<" 人\n"; cout<<"\n 所有学生数学平均成绩:"<<SX/len<<"分\n"; cout<<"\n 所有学生语文平均成绩:"<<YW/len<<"分\n"; cout<<"\n 所有学生英语平均成绩:"<<YY/len<<"分\n"; return; } } } //查询最高分 void selectmax() { STU* p = Head->next; int maxyw=0; int maxsx=0; int maxyy=0; STU* qyw = NULL; STU* qyy = NULL; STU* qsx = NULL; while (p != NULL) { if(p->Chinese>maxyw) { maxyw=p->Chinese; qyw = p; //保存该节点信息 } if(p->English>maxyy) { maxyy=p->English; qyy = p; //保存该节点信息 } if(p->Math>maxsx) { maxsx=p->Math; qsx = p; //保存该节点信息 } p = p->next; } if (p == NULL) { cout<<"\n 语文最高分学生成绩信息如下!\n"; cout<<"\t学号\t姓名\t语文\n"; cout<<"\t"<<qyw->num<<"\t"<<qyw->name<<"\t"<<qyw->Chinese<<endl; cout<<"\n 数学最高分学生成绩信息如下!\n"; cout<<"\t学号\t姓名\t数学\n"; cout<<"\t"<<qsx->num<<"\t"<<qsx->name<<"\t"<<qsx->Math<<endl; cout<<"\n 英语最高分学生成绩信息如下!\n"; cout<<"\t学号\t姓名\t英语\n"; cout<<"\t"<<qyy->num<<"\t"<<qyy->name<<"\t"<<qyy->English<<endl; } } //对学生的总分成绩进行排序(直插法) void sort() { STU* p = Head->next; if(p!=NULL) { STU* q=p->next; p->next=NULL; //断开头结点,依次将q插入有序表中 STU* r; //r指向下一个元素 STU* s; //s指向该有序链表的表头 while(q) { r=q->next; s=Head; //s从头开始移动,查找q应该插入的位置 while(s->next && (s->next->avg >q->avg)) { s=s->next; } q->next=s->next; s->next=q; q=r; } } STU* p1 = Head->next; cout<<"\t学号\t姓名\t性别\t专业\t\t总分\t\t排名\n\n"; int rank=1; while (p1 != NULL) { double sum = p1->Math + p1->Chinese + p1->English; p1->rank=rank; rank++; cout<<"\t"<<p1->num<<"\t"<<p1->name<<"\t"<<p1->sex<<"\t"<<p1->subject<<"\t\t"<<sum<<"\t\t"<<p1->rank<<endl; p1 = p1->next; } } //查询该专业所有人 void selectsubject() { cout<<"请输入你要查询的专业:"; string subject1; cin>>subject1; STU* p = Head->next; int sum=0; cout<<"\t学号\t姓名\t性别\t专业\t\t数学\t语文\t英语\n\n"; while(p!=NULL) { if(strcmp(p->subject,subject1.c_str())==0) //dept.c_str(),把string转化成char[],strcmp字符串比较 { sum++; cout<<"\t"<<p->num<<"\t"<<p->name<<"\t"<<p->sex<<"\t"<<p->subject<<"\t\t"<<p->Math <<"\t"<<p->Chinese<<"\t"<<p->English<<endl; p=p->next; } else p=p->next; } cout<<"本专业一共有"<<sum<<"名学生"<<endl; } void select1(){ } //文件保存 void WriteFile() { fstream IO_File; size_t num(0); STU *p=Head->next; while (p!=NULL) { num++; //统计节点数量 p=p->next; } if(num==0) IO_File.open("stud.dat",ios::in|ios::app|ios::out|ios::binary|ios::trunc); //ios::app以追加的形式写入信息,不会覆盖上次文件信息 if(!IO_File) { cout<<"没有找到文件"<<endl; } else { p=Head->next; for(size_t i=0;i<num;i++) { p->avg=(p->Chinese+p->English+p->Math)/3; IO_File.write((char*)&(*p),sizeof(stu)); //把该学生对象写入文件 p=p->next; } IO_File.close(); cout<<"文件已保存!"<<endl; } } //输出文件全部记录 void OutputFile() { fstream IO_File("stud.dat",ios::in|ios::out|ios::binary); if(!IO_File) { cout<<"没有找到文件"<<endl; } else { stu m_TmpStudent; IO_File.seekg(0,ios::end);//在文件中尾指针 streampos spEnd =IO_File.tellg(); IO_File.seekg(0,ios::beg);//在文件中头指针 streampos spBeg =IO_File.tellg(); size_t dataLength= spEnd - spBeg;//文件总长 size_t dataSize = dataLength /sizeof(stu);//读取文件中学生个数 End=Head; for(size_t i=0;i<dataSize;i++) { STU *s; s=(stu *)malloc(sizeof(stu));//开辟缓存空间暂存学生信息 IO_File.read((char*)&m_TmpStudent,sizeof(stu));//读取文件信息 *s=m_TmpStudent; s->next=NULL; if(Head->next==NULL) { Head->next=s; End=End->next; End->next=NULL; } else { End->next=s; End=End->next; End->next=NULL; } End->avg=(End->Chinese+End->English+End->Math)/3; cout<<"\t学号\t姓名\t性别\t专业\t\t数学\t语文\t英语\t平均分\n"; cout<<"\t"<<End->num<<"\t"<<End->name<<"\t"<<End->sex<<"\t"<<End->subject<<"\t\t"<<End->Math <<"\t"<<End->Chinese<<"\t"<<End->English<<"\t"<<End->avg; cout<<endl; } } IO_File.close();//关闭文件 } void BinInsertSort(Index R[],int n) //采用折半插入排序 { int i,j,low,high,mid; Index temp; for(i=1;i<n;i++) { if(R[i].no<R[i-1].no) { temp=R[i]; low=0; high=i-1; while(low<=high) { mid=(low+high)/2; if(temp.no<R[mid].no) high=mid-1; else low=mid+1; } for(j=i-1;j>=high+1;j--) R[j+1]=R[j]; R[high+1]=temp; } } } //创建索引文件 void CreatIdxFile() { stu st; Index idex[Maxsize]; Index vessel;//一个缓存的容器 int num(0); fstream IO_File("stud.dat",ios::in|ios::out|ios::binary); if(!IO_File) { cout<<"The stud.dat file is error!"<<endl; } else { IO_File.seekg(0,ios::end);//在文件中尾指针 streampos spEnd =IO_File.tellg(); IO_File.seekg(0,ios::beg);//在文件中头指针 streampos spBeg =IO_File.tellg(); size_t dataLength= spEnd - spBeg;//文件总长 size_t dataSize = dataLength /sizeof(stu);//学生数量 num=dataSize; for(size_t i=0;i<dataSize;i++) { IO_File.read((char*)&st,sizeof(stu)); idex[i].no=st.num; strcpy(idex[i].name,st.name); idex[i].offset=i+1; } BinInsertSort(idex,dataSize); //对idx数组按no值排序 fstream IO_File_index("index.dat",ios::in|ios::out|ios::binary); if(!IO_File_index) { cout<<" 提示:不能建立索引文件\n"; } else { for(size_t i=0;i<num;i++) { vessel=idex[i]; //把idex数组的信息存入到缓存容器中 IO_File_index.write((char*)&(vessel),sizeof(Index)); } cout<<" 提示:索引文件建立完毕\n"; } IO_File_index.close(); } IO_File.close(); } //读取索引数组 void ReadIndexFile(Index index[],int &n) { Index idex; fstream IO_File("index.dat",ios::in|ios::out|ios::binary); if(!IO_File) { cout<<" 提示:索引文件不能打开"<<endl; return ; } else { IO_File.seekg(0,ios::end);//在文件中尾指针 streampos spEnd =IO_File.tellg(); IO_File.seekg(0,ios::beg);//在文件中头指针 streampos spBeg =IO_File.tellg(); size_t dataLength= spEnd - spBeg;//文件总长 size_t dataSize = dataLength /sizeof(Index);//一个结构体的长 n=dataSize; for(size_t i=0;i<dataSize;i++) { IO_File.read((char*)&idex,sizeof(Index)); //读取信息到idex index[i]=idex; //将idex的信息存入到index数组中 } } IO_File.close();//关闭文件 } int SearchNum(Index idx[],int n,int no) { int mid,low=0,high=n-1; while (low<=high) //二分查找 { mid=(low+high)/2; if (idx[mid].no>no) high=mid-1; else if (idx[mid].no<no) low=mid+1; else return idx[mid].offset; } return 0; } //输入学号查找学生 void Find_Student() { int no; stu st; Index idx[Maxsize]; int i,n; fstream IO_File("stud.dat",ios::in|ios::out|ios::binary); if(!IO_File) { cout<<"提示:主文件中没有任何记录!"<<endl; return ; } ReadIndexFile(idx,n); //读取索引数组idx cout<<"输入学号:"; cin>>no; i=SearchNum(idx,n,no)-1; //在idx中查找 if (i==-1) { printf(" 提示:学号%d不存在\n",no); cout<<endl; } else { IO_File.seekg(0,ios::end);//在文件中尾指针 streampos spEnd =IO_File.tellg(); IO_File.seekg(0,ios::beg);//在文件中头指针 streampos spBeg =IO_File.tellg(); size_t dataLength= spEnd - spBeg;//文件总长 size_t dataSize = dataLength /sizeof( stu);//一个结构体的长 size_t j=0; for(j;j<dataSize;j++) { IO_File.read((char*)&st,sizeof( stu)); //读取文件信息到st if(j==i) { cout<<"\t学号\t姓名\t性别\t专业\t\t数学\t语文\t英语\t平均分\n"; cout<<"\t"<<st.num<<"\t"<<st.name<<"\t"<<st.sex<<"\t"<<st.subject<<"\t\t"<<st.Math <<"\t"<<st.Chinese<<"\t"<<st.English<<"\t"<<st.avg<<endl; IO_File.close();//关闭文件 return ; } } if(j==dataSize){cout<<"查无此人!"<<endl;} } IO_File.close();//关闭文件 } int SearchNum_2(Index idx[],int n,string name) { for(int i=0;i<n;i++) { if (strcmp(idx[i].name,name.c_str())==0) { return idx[i].offset; } } return 0; } //通过姓名查找学生 void FindStudentname() { string name; stu st; Index idx[Maxsize]; int i,n; fstream IO_File("stud.dat",ios::in|ios::out|ios::binary); if(!IO_File) { cout<<"提示:主文件中没有任何记录!"<<endl; return ; } ReadIndexFile(idx,n); //读取索引数组idx printf("输入姓名:"); cin>>name; i=SearchNum_2(idx,n,name)-1; //在idx中查找 if (i==-1) { cout<<" 提示:姓名:"<<name<<"不存在"<<endl; cout<<endl; } else { IO_File.seekg(0,ios::end);//在文件中尾指针 streampos spEnd =IO_File.tellg(); IO_File.seekg(0,ios::beg);//在文件中头指针 streampos spBeg =IO_File.tellg(); size_t dataLength= spEnd - spBeg;//文件总长 size_t dataSize = dataLength /sizeof( stu);//一个结构体的长 size_t j=0; for(j;j<dataSize;j++) { IO_File.read((char*)&st,sizeof( stu)); if(j==i) { cout<<"\t学号\t姓名\t性别\t专业\t\t数学\t语文\t英语\t平均分\n"; cout<<"\t"<<st.num<<"\t"<<st.name<<"\t"<<st.sex<<"\t"<<st.subject<<"\t\t"<<st.Math <<"\t"<<st.Chinese<<"\t"<<st.English<<"\t"<<st.avg<<endl; IO_File.close();//关闭文件 return ; } } } IO_File.close();//关闭文件 } //输出索引文件 void OutputIdxFile() { Index idex; fstream IO_File("index.dat",ios::in|ios::out|ios::binary); if(!IO_File) { cout<<"The index.dat file is error!"<<endl; return ; } else { IO_File.seekg(0,ios::end);//在文件中尾指针 streampos spEnd =IO_File.tellg(); IO_File.seekg(0,ios::beg);//在文件中头指针 streampos spBeg =IO_File.tellg(); size_t dataLength= spEnd - spBeg;//文件总长 size_t dataSize = dataLength /sizeof(Index);//一个结构体的长 printf(" ----学生索引表----\n"); printf("\t学号 记录号 姓名\n"); for(size_t i=0;i<dataSize;i++) { IO_File.read((char*)&(idex),sizeof(Index)); printf("\t%3d%6ld%11s\n",idex.no,idex.offset,idex.name); } } IO_File.close();//关闭文件 } void file() { cout<<"\t\t***************************************"<<endl; cout<<"\t\t** 欢迎来到文件管理系统 **"<<endl; cout<<"\t\t** 1.保存学生信息 **"<<endl; cout<<"\t\t** 2.读取学生信息 **"<<endl; cout<<"\t\t** 3.建立索引文件 **"<<endl; cout<<"\t\t** 4.输出索引文件 **"<<endl; cout<<"\t\t** 5:按学号查找 **"<<endl; cout<<"\t\t** 6:按姓名查找 **"<<endl; cout<<"\t\t** 0:退出 **"<<endl; cout<<"\t\t***************************************"<<endl; int select(1); while(select!=0) { cout<<"请选择对应功能:"; cin>>select; switch(select) { case 1: WriteFile(); break; case 2: OutputFile() ; break; case 3: CreatIdxFile(); break; case 4: OutputIdxFile(); break; case 5: Find_Student(); break; case 6: FindStudentname(); break; case 0: break; } } } //需要执行的功能选择 void Choice(int k) { while (1) { switch (k) { case 1: { while (1) { AddStudent(); cout<<"\n是否继续添加学生成绩信息 继续:1 / 退出:0: "; int select1 ; cin>>select1; switch (select1) { case 1: break; case 0: return; default: return; } } } case 2: { while (1) { DeleteStudent(); cout<<"\n是否继续删除学生成绩信息 继续:1 / 退出:0: "; int select2 ; cin>>select2; switch (select2) { case 1: break; case 0: return; default: return; } } } case 3: { while (1) { AlterStudent(); cout<<"\n是否继续更改学生成绩信息 继续:1 / 退出:0: "; int select3 ; cin>>select3; switch (select3) { case 1: break; case 0: return; default: return; } } } case 4: { while (1) { SeekStudent(); cout<<"\n是否继续查询学生成绩信息 继续:1 / 退出:0: "; int select4; cin>>select4; switch (select4) { case 1: break; case 0: return; default: return; } } } case 5: { while (1) { DisplayAll(); cout<<"\n是否退出显示 退出:1 / 刷新:0: "; int select5 ; cin>>select5; switch (select5) { case 1: return; case 0: break; default: return; } } } case 6: { while (1) { sort(); cout<<"\n是否退出排序 退出:1 / 刷新:0: "; int select6 ; cin>>select6; switch (select6) { case 1: return; case 0: break; default: return; } } } case 7: { while (1) { selectsubject(); cout<<"\n是否退出查询专业 退出:1 / 刷新:0: "; int select7 ; cin>>select7; switch (select7) { case 1: return; case 0: break; default: return; } } } case 8: { while (1) { selectmax(); cout<<"\n是否退出查询最高分 退出:1 / 刷新:0: "; int select8 ; cin>>select8; switch (select8) { case 1: return; case 0: break; default: return; } } } case 9: { while (1) { file(); return; } } default: { cout<<"\n\n 输入错误! 按任意键回到主界面\n\n"; system("pause"); return; } } } } int main() { CreatList(); int key; while (1) { menu(); cin>>key; Choice(key); } return 0; }
界面功能图展示:
添加功能:
查询功能:
输出功能:
按专业查询:
剩余功能图请自行查看,第一次写博客,有任何问题欢迎指正