参加一个c语言比赛,写个项目,学生成绩管理系统,用单项链表写的,有什么功能,很出彩

2025-04-05 19:49:01
推荐回答(1个)
回答1:

#include 
#include 
#include 

#define _COURSES 3//定义科目数
#define _LEN sizeof(student)//定义结构体大小

//枚举返回值情况
enum status {
OVERFLOW = -1, //内存(溢出)问题
DONE = 0, //成功
NOFOUND = 1, //不存在
OPENFAIL = 2, //打开(文件)失败
BACK = 3 //返回
};
typedef struct StudentInfo {
//数据域
unsigned int num;//学号
char name[11];//姓名
float scores[_COURSES];//各科成绩
//指针域
struct StudentInfo *next;//存放下一节点的地址
}student;
//end

student *head = NULL;//声明链表头结点
student *curr = NULL;//声明指向当前节点的指针
int total = 0;//声明当前节点个数



int init();//初始化链表
int add_stu();//添加新节点
int show_all();//显示所有学生信息
int find_stu();//查找指定信息节点
int modify_stu();//修改指定信息节点
int remove_stu();//删除指定信息节点
int sort_list();//对链表排序
int save_to_file();//将所有信息保存至文件
int read_from_file();//从文件中读取信息
void about();//关于
int quit();//释放所有节点空间

int entering(student *input);//录入学生信息
void show_stu(student *show, int serial);//显示指定学生信息
void start();//程序开始界面
void change(student *former, student *latter, student *temp);

void main() {
int choice = 0;
init();
while(1) {
system("cls");
start();
printf("请选择:");
scanf("%d",&choice);
fflush(stdin);//清空缓冲区
switch (choice) {
case 1: add_stu(); break;
case 2: show_all(); break;
case 3: find_stu(); break;
case 4: modify_stu(); break;
case 5: remove_stu(); break;
case 6: sort_list(); break;
case 7: save_to_file(); break;
case 8: read_from_file(); break;
case 9: about(); break;
case 0: quit(); exit(0); break;
default: break;
}
system("pause");
}
}

int init() {
head = (student *)malloc(_LEN);//为头结点申请空间
if (!head) {//如果申请空间失败,返回
return OVERFLOW;
}
head->next = NULL;//指向下一节点(空)
curr = head->next;//当前节点指针指向第一个结点
total = 0;//当前节点个数初始化为0(头结点不计算在内)

return DONE;
}

int add_stu() {
student *add = (student *)malloc(_LEN);
curr = head->next;//当前节点指针指向第一个节点

printf("\t====当前已存入 %d 个同学\n",total);
printf("请输入第 %d 个学生的信息\n",total + 1);
if (BACK == entering(add)) {
free(add);
return BACK;
}

head->next = add;//头结点指针域指向新建的节点
add->next = curr;//新建节点指针域指向第一个节点
curr = add;  //当前节点指向新建的节点
total += 1;  //更新学生总人数
return DONE;
}
int show_all() {
if(0 == total) {
printf("\t====没有可供显示的学生信息!\n");
return NOFOUND;
}

curr = head->next;//当前节点指针指向第一个节点

printf("\t%4s%12s%12s","序号","学号","姓名");
for(int m = 0; m <_COURSES; m++) {
printf("%7s","科目");
}
printf("\n");
printf("\t-------------------------------------------------------------\n");

for(int i = 1; i<=total; i++) {
show_stu(curr,i);
curr = curr->next;//当前节点指针后移
}
printf("\t-------------------------------------------------------------\n");
return DONE;
}
int find_stu() {
char stu_name[11];
int flag=1;
printf("请输入要查找的学生姓名:");
scanf("%s",stu_name);
curr = head->next;//指向第一个节点
while (curr != NULL) {
if (strcmp(stu_name,curr->name) == 0) {
printf("\t%4s%12s%12s","序号","学号","姓名");
for (int m=0; m< _COURSES; m++) {
printf("%7s","科目");
}
printf("\n");
printf("\t-------------------------------------------------------------\n");
show_stu(curr,flag);
return DONE;
}
curr = curr->next;
++flag;
}
printf("\t====没有找到 %s !请仔细核对姓名再查找\n",stu_name);
return NOFOUND;
}

int modify_stu() {
char stu_name[11];
int flag = 1;
curr = head->next;//指向第一个节点
printf("请输入要修改的学生的姓名:");
scanf("%s",stu_name);
while(curr != NULL) {
if(strcmp(stu_name,curr->name) == 0) {
printf("\t%4s%12s%12s","序号","学号","姓名");
for(int m = 0; m < _COURSES; m++) {
printf("%7s","科目");
}
printf("\n");
printf("\t-------------------------------------------------------------\n");
show_stu(curr,flag);

entering(curr);
printf("\t====成功修改了 %s 的所有信息!\n",stu_name);

return DONE;
}
curr = curr->next;
++flag;
}
printf("\t====没有找到 %s !请仔细核对姓名\n",stu_name);
return NOFOUND;
}


int remove_stu() {
student *pre=head;
char stu_name[11];
curr = head->next;//指向第一个节点
printf("请输入要删除的学生的姓名:");
scanf("%s",stu_name);

while (curr != NULL) {
if (strcmp(stu_name,curr->name) == 0) {
pre->next = curr->next; //
free(curr); //
--total; //
printf("\t====已成功删除\"%s\"\n",stu_name);

return DONE;
}
pre = pre->next;
curr = curr->next;
}
printf("\t====没有找到 %s !请仔细核对姓名\n",stu_name);
return NOFOUND;
}


int sort_list() {
student *temp = (student *)malloc(_LEN);
student *curr_i = head->next;
student *curr_j = NULL;
char choice='0';

printf("\t \t1----按学号排序 .\t2----按姓名排序 .           \n");
printf("\t \t3----按科目排序 .\t0----退 出 排 序.           \n"); 
printf("请选择:");
scanf("%c",&choice);
fflush(stdin);
switch (choice) {
case '1': {
while(curr_i->next != NULL) {
curr_j = curr_i->next;
while (curr_j != NULL) {
if (curr_i->num > curr_j->num) {
change(curr_i,curr_j,temp);
}
curr_j = curr_j->next;
}
curr_i = curr_i->next;
}
printf("\t====排序成功!\n");
break;
}
case '2': {
while(curr_i->next != NULL) {
curr_j = curr_i->next;
while (curr_j != NULL) {
if (strcmp(curr_i->name , curr_j->name) > 0) {
change(curr_i,curr_j,temp);
}
curr_j = curr_j->next;
}
curr_i = curr_i->next;
}
printf("\t====排序成功!\n");
break;
}
case '3': {
while(curr_i->next != NULL) {
curr_j = curr_i->next;
while (curr_j != NULL) {
if (curr_i->scores[0] < curr_j->scores[0]) {
change(curr_i,curr_j,temp);
}
curr_j = curr_j->next;
}
curr_i = curr_i->next;
}
printf("\t====排序成功!\n");
break;
}
case '0': {
free(temp);
return BACK;
}
default: {
printf("\t====输入有误!\n");
break;
}
}
free(temp);
return DONE;
}

int save_to_file() {
curr = head->next;
if (total == 0) {
printf("\t====目前还没有任何信息,不用保存!\n");
return BACK;
}

FILE *fp;
if((fp=fopen("record.dat","wb"))==NULL) {
printf("\t====文件打开失败!\n");
return OPENFAIL;
}
while (curr != NULL) {
//将数据成块写入文件
fwrite((char *)curr, _LEN, 1, fp);
curr = curr->next;
}
fclose(fp);
printf("\t====信息已成功保存至文件\"record.dat\"文件中\n");

return DONE;
}

int read_from_file() {
char judge='y';
FILE *fp;

if((fp = fopen("record.dat","r")) == NULL) {
printf("文件不存在或者打开失败!\n");
return OPENFAIL;
}
printf("\t====读取文件会覆盖当前信息!是否确定载入文件?(y/n):");
scanf("%c",&judge);
if (judge=='n' || judge=='N') {
return BACK;
}

quit();//释放以前所有信息的空间
init();//重新初始化链表
curr = head;//当前节点指针指向头结点

student *add=(student *)malloc(_LEN);//申请空间存放读取的信息

while (fread((char *)add, _LEN, 1, fp)) { //由于存储的信息是最新的信息在前,所以读取的时候将其添加在链表尾
add->next=curr->next;
curr->next=add;
curr=add;
add=(student *)malloc(_LEN);
++total;
}
fclose(fp);
printf("\t====文件载入成功!当前已有%d个学生。\n",total);

return DONE;
}

void about() {
printf("\t#############################################################\n");
printf("\n\t \t欢迎各位用户反馈、提出宝贵的意见和建议  \n");                         
printf("\t \t联系方式  \n");            
printf("\t \t手  机:13815601299  \n");
printf("\t \tE-mail:876929541@QQ.com  \n");
printf("\n\t \t\tC语言学生成绩管理系统1.0版\n\n");
printf("\t#############################################################\n");
}

int quit() {
curr =head->next;
student *temp=curr;
while(curr != NULL) {
temp=curr->next;
free(curr);
curr=temp;
}
curr=NULL;
temp=NULL;
free(head);//释放头节点
return DONE;
}

int entering(student *input) {
printf("\n请输入学生的学号(输入0退出添加):");
scanf("%d",&input->num);
if (0 == input->num) {
return BACK;
}

printf("请输入学生的姓名(五个汉字以内):");
scanf("%s",input->name);

printf("请输入%d门科目的成绩(用空格隔开):", _COURSES);
for (int i=0; i<_COURSES; i++) {
scanf("%f",&input->scores[i]);
}

return DONE;
}

void show_stu(student *show, int serial) {
printf("\t%4d%12d%12s",serial,show->num,show->name);
for (int i = 0; i < _COURSES; i++) {
printf("%7.1f",show->scores[i]);
}
printf("\n");
}

void start() {
printf("\n");
printf("\t\t\t欢迎使用学生成绩管理系统\n");
printf("\t*************************************************************\n");
printf("\t|\t1----添 加 学 生.\t2----显 示 信 息.          |\n");                         
printf("\t|\t3----查 找 学 生.\t4----修 改 信 息.          |\n");            
printf("\t|\t5----删 除 学 生.\t6----学 生 排 序.          |\n");
printf("\t|\t7----信 息 存 档.\t8----读 取 存 档.          |\n");
printf("\t|\t9----关       于.\t0----退       出.          |\n");
    printf("\t*************************************************************\n");
}

void change(student *former, student *latter,student *temp) {
*temp = *former;
strcpy(former->name , latter->name);
strcpy(latter->name , temp->name);
former->num = latter->num;
latter->num = temp->num;
for (int i=0; i<_COURSES; i++) {
former->scores[i] = latter->scores[i];
latter->scores[i] = temp->scores[i];
}
}