看到论坛里总有学生在寻求链表实现学生成绩管理的帖子,动手写一个,也算学习,虽然功能很少,以前还真没写过完整的,写的比较粗糙,比较简单,不合适的地方欢迎指正。
LinkTable.h
class StudentInfo { public: char code[6]; float chinesescore; float mathscore; StudentInfo* next; StudentInfo* prior; }; //添加学生信息,如果prior为NULL,则newinfo为头结点 StudentInfo* AddInfo(StudentInfo* prior,StudentInfo* newinfo); //根据编号删除学生信息 bool DelStudentInfo(char* code,StudentInfo*& pHead); //根据编号查找学生信息 StudentInfo* FindStudentInfoByCode(char* code,StudentInfo* pHead); //修改学生成绩信息 void ModifyStudentInfo(StudentInfo* p); //从头结点开始打印学生信息 void PrintStudentInfo(StudentInfo* pHead); //对指定的节点输入学生信息 void InputInfo(StudentInfo* pInfo); //获取最后一个节点 StudentInfo* GetLastStudentInfo(StudentInfo* pHead); //保存链表到文件,顺序保存 void SaveStudentInfoToFile(char* filename,StudentInfo* pHead); //从文件中读取链表 void LoadStudentInfoFromFile(char* filename,StudentInfo*& pHead); //操作提示 void ShowOperateInfo(void);
LinkTable.cpp
#include "LinkTable.h" #include <stdio.h> #include <string.h> //添加学生信息,如果prior为NULL,则newinfo为头结点 StudentInfo* AddInfo(StudentInfo* prior,StudentInfo* newinfo) { if (!prior) { newinfo->next = NULL; newinfo->prior = NULL; } else { prior->next = newinfo; newinfo->prior = prior; newinfo->next = NULL; } memset(newinfo->code,0,sizeof(newinfo->code)); InputInfo(newinfo); return newinfo; } //根据编号删除学生信息 bool DelStudentInfo(char* code,StudentInfo*& pHead) { StudentInfo* pDel = FindStudentInfoByCode(code,pHead); if (pDel == NULL) return false; else { if (pDel == pHead) pHead = pDel->next; else { pDel->prior->next = pDel->next; if (pDel->next != NULL) pDel->next->prior = pDel->prior; } delete pDel; pDel = NULL; return true; } } //根据编号查找学生信息 StudentInfo* FindStudentInfoByCode(char* code,StudentInfo* pHead) { StudentInfo* p = pHead; while (p != NULL) { if (strcmp(p->code,code) == 0) { return p; } p = p->next; } return NULL; } //修改学生成绩信息 void ModifyStudentInfo(StudentInfo* p) { printf("%s号学生当前信息:语文:%f,数学:%f/n",p->code,p->chinesescore,p->mathscore); printf("%s","请输入修改后的语文成绩:"); scanf("%f",&p->chinesescore); printf("%s","请输入修改后的数学成绩:"); scanf("%f",&p->mathscore); printf("修改完毕,%s号学生最新信息:语文:%f,数学:%f/n",p->code,p->chinesescore,p->mathscore); } //从头结点开始打印学生信息 void PrintStudentInfo(StudentInfo* pHead) { StudentInfo* p = pHead; while (p!=NULL) { printf("%s号学生:语文:%f,数学:%f/n",p->code,p->chinesescore,p->mathscore); p = p->next; } } //对指定的节点输入学生信息 void InputInfo(StudentInfo* pInfo) { printf("%s","请输入学生编号:"); scanf("%s",pInfo->code); printf("%s","请输入语文成绩:"); scanf("%f",&pInfo->chinesescore); printf("%s","请输入数学成绩:"); scanf("%f",&pInfo->mathscore); } //获取最后一个节点 StudentInfo* GetLastStudentInfo(StudentInfo* pHead) { if (pHead == NULL) return NULL; StudentInfo* p = pHead; while (p) { if (p->next == NULL) return p; p = p->next; } } //保存链表到文件,顺序保存 void SaveStudentInfoToFile(char* filename,StudentInfo* pHead) { FILE* f; f= fopen(filename,"w"); StudentInfo* p = pHead; while (p) { fwrite(p->code,sizeof(char),sizeof(p->code),f); fwrite(&p->chinesescore,sizeof(float),1,f); fwrite(&p->mathscore,sizeof(float),1,f); //fwrite("/n",sizeof(char),1,f); p=p->next; } //fwrite("/0",sizeof(char),1,f); fclose(f); } //从文件中读取链表 void LoadStudentInfoFromFile(char* filename,StudentInfo*& pHead) { FILE* f; f= fopen(filename,"r"); if (f == NULL) return; fseek(f, 0, SEEK_SET); StudentInfo* p = NULL; StudentInfo* newp = NULL; int c; //c = fgetc(f); while (!feof(f)) { //因为不能完全依赖feof判断文件是否到结尾,所以用fgetc的返回值来判断, //当读取到结尾时,feof实际并没有获得到达结尾的信息,所以这里用fgetc继续读取一个字符,来判断是否结束 //如果不是-1(结尾),那么回退一个文件位置,如果是-1,退出 c = fgetc(f); if (c != -1) fseek(f, -1, SEEK_CUR); else return; if (pHead == NULL) { pHead = new StudentInfo; pHead->next = NULL; pHead->prior = NULL; memset(pHead->code,0,sizeof(pHead->code)); fread(pHead->code,sizeof(char),sizeof(pHead->code),f); fread(&pHead->chinesescore,sizeof(float),1,f); fread(&pHead->mathscore,sizeof(float),1,f); p = pHead; } else { newp = new StudentInfo; newp->next = NULL; newp->prior = NULL; newp->prior = p; memset(newp->code,0,sizeof(newp->code)); fread(newp->code,sizeof(char),sizeof(newp->code),f); fread(&newp->chinesescore,sizeof(float),1,f); fread(&newp->mathscore,sizeof(float),1,f); p->next = newp; p = newp; } } fclose(f); } //操作提示 void ShowOperateInfo(void) { printf("%s/n","1:增加信息"); printf("%s/n","2:删除信息"); printf("%s/n","3:查找信息"); printf("%s/n","4:修改信息"); printf("%s/n","5:保存信息"); printf("%s/n","9:打印信息"); printf("%s/n","0:结束"); }
Main方法
#include "LinkTable.h" int main() { ShowOperateInfo(); int i; //curInfo当前节点,用来添加节点用 StudentInfo* curInfo = new StudentInfo; StudentInfo* pHead = NULL; LoadStudentInfoFromFile("e://link.txt",pHead); //将curInfo指向最后一个节点 if (pHead != NULL) curInfo = GetLastStudentInfo(pHead); char code[10]={0}; while (true) { printf("%s","请输入操作号:"); scanf("%d",&i); switch (i) { //退出 case 0: exit(0); //添加 case 1: if (pHead == NULL) { pHead = new StudentInfo; curInfo = pHead = AddInfo(NULL,pHead); } else { StudentInfo* newInfo = new StudentInfo; curInfo = AddInfo(curInfo,newInfo); } break; //删除 case 2: printf("%s","请输入要删除的学生编号:"); scanf("%s",code); DelStudentInfo(code,pHead); curInfo = GetLastStudentInfo(pHead); break; //查找 case 3: printf("%s/n","请输入要查找的学生编号:"); scanf("%s",code); { StudentInfo* p = FindStudentInfoByCode(code,pHead); if (p == NULL) printf("编号%s不存在",code); else { printf("%s号学生:语文:%f,数学:%f/n",p->code,p->chinesescore,p->mathscore); } } break; //修改 case 4: printf("%s/n","请输入要修改的学生编号:"); scanf("%s",code); { StudentInfo* p = FindStudentInfoByCode(code,pHead); if (p == NULL) printf("编号%s不存在",code); else { ModifyStudentInfo(p); } } break; case 5: SaveStudentInfoToFile("e://link.txt",pHead); break; //打印 case 9: PrintStudentInfo(pHead); break; default: exit(0); } } }
运行结果: