C++编写学生管理系统(文件加单链表)

问题遇到的现象和发生背景

不知道如何下手

问题相关代码,请勿粘贴截图
运行结果及报错内容

已经摸索三周了,前几天改了一个别人的代码,但是改不好了

我的解答思路和尝试过的方法

查找别人的代码,取其精华,去其糟粕

我想要达到的结果

你这是什么?

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int Nstudent; //用于储存学生的数量
char filename[50]; //用于储存文件的名字
FILE *FP; //文件指针
typedef struct Student
{
int id; //储存学号
char name[10];//储存学生姓名
char grade[10];//储存学生年纪
char sex[5];//储存学生性别
double C_language,math,enlish;//储存学生成绩
struct Student *next; //储存下一个节点的地址
} Student;
Student head=NULL; //定义头指针
void WriteData(); //此函数用于为新创建的文件写数据
void ReadData(); //此函数用于将文件中的数据读入链表中
void Search();
void Append(); //此函数用于添加数据
void ModifyData(Student p);//此函数用于修改学生的数据
Student
SearchByName(); /此函数用于按学生姓名查找并返回地址/
Student
SearchById(); /此函数用于按学生学号查找并返回地址/
void CreateFile(); /此函数用于创建一个文件/
void List(); //此函数用列出学生信息
int Menu(); //菜单
void sortstudent();
void ModifyStudentData(); //此函数用于查找学生并修改此学生的信息
void DeletedData(); //此函数用于删除数据
int Quit(); //此函数用于退出系统
int main( )
{

while(1)
{

switch(Menu())              //选择函数,实现某种功能
{
  case 0:if(Quit())return 0;break;
  case 1:WriteData();break;
  case 2:List();break;
  case 3:sortstudent();break;
  case 4:DeletedData();break;
  case 6:Search();break;
  case 7:ModifyStudentData() ;break;
 // case 8:
}

}
return 0;
}
/此函数用于把链表中的数据写入文件/
void CreateFile()
{
if(head!=NULL)
{
printf("还有数据未保存,请保存,按任意键继续");
getchar();
return;
}
printf("请输入要创建的文件的名字:");
scanf("%s",&filename);
FP=fopen(filename,"w");

}
/此函数用于为新创建的文件写数据/
void WriteData()
{ CreateFile();
if((FP=fopen(filename,"w"))==NULL)
{
printf("Cannot open this file.\n");
exit(1);
}
printf("请输入学生的人数:");
scanf("%d",&Nstudent);
printf("\n");
fprintf(FP,"%d\n",Nstudent);
Student *p,*p1;
for(int i=0;i<Nstudent;i++) //有几名学生循环几次
{
p=(Student*)malloc(sizeof(Student)); //动态分配内存
printf("请输入第%d名学生的学号:",i+1);
scanf("%d",&p->id);
printf("\n");
fprintf(FP,"%d\n",p->id);
printf("请输入第%d名学生的姓名:",i+1);
scanf("%s",&p->name);
printf("\n");
fprintf(FP,"%s\n",p->name);
printf("请输入第%d名学生的性别:",i+1);
scanf("%s",&p->sex);
printf("\n");
fprintf(FP,"%s\n",p->sex);
printf("请输入第%d名学生的班级:",i+1);
scanf("%s",&p->grade);
fprintf(FP,"%s\n",p->grade);
printf("\n");
printf("请输入C语言成绩:");
scanf("%lf",&p->C_language);
printf("\n");
fprintf(FP,"%f\n",p->C_language);
printf("请输入数学的成绩:");
scanf("%lf",&p->math);
printf("\n");
fprintf(FP,"%f\n",p->math);
printf("请输入英语的成绩:");
scanf("%lf",&p->enlish);
printf("\n");
fprintf(FP,"%f\n",p->enlish);
if(head==NULL) //如果头指针为空指针将数据储存在头指针所指向的内存单元
{
head=p;
p->next=NULL;

        p1=head;
    }
    else
    {
       p1->next=p;
       p->next=NULL;
       p1=p1->next;
    }
}
printf("按任意键继续\n");
getchar();
getchar();
return;

}
/此函数用于将文件中的数据读入链表中/
void ReadData()
{
if(FP==NULL)
{
printf("请打开文件,按任意键继续");
getchar();
getchar();
return;
}
fscanf(FP,"%d",&Nstudent); //从文件中读取学生的人数和学科的数量
Student *p,p1;
for(int i=0;i<Nstudent;i++)
{
p=(Student*)malloc(sizeof(Student)); //动态分配内存
fscanf(FP,"%d%s%s%s",&p->id,&p->name,&p->grade,&p->sex);
fscanf(FP,"%lf%lf%lf",&p->C_language,&p->math,&p->enlish);
if(head==NULL) //如果头指针为空指针将数据储存在头指针所指向的内存单元
{
head=p;
head->next=NULL;
p1=head;
}
else
{
p1->next=p;
p->next=NULL;
p1=p1->next;
}
}
printf("按任意键继续\n");
getchar();
getchar();
}
void sortstudent()//按学号进行排序
{ Student
p1,*p2,*p;
system("cls");
printf("\n\n");
Student *q=p->next;
int len=0,t;
while(q!=NULL)
{
len++;
q=q->next;
}

for(int i=0;i<len;i++)
{
    head=p->next;

    for(int j=0;j<len-i-1;j++)
        p1=q;
        p2=q->next;
        if(p1->id > p2->id)
        {
            t = p1->id;
            p1->id = p2->id;
            p2->id = t;
        }
        head=q->next;
}

printf("\t\t\t排序完成");
system("pause");
}
/此函数用于在链表后面添加数据/
//void Append( )
//{
// if(FP==NULL)
// {
// printf("请打开一个文件,按任意键继续\n");
// getchar();
// getchar();
// return ;
// }
// Student *p;
// Student *p1;
// p1=head;
// while(p1->next)
// {
// p1=p1->next;
// }
// printf("输入要添加学生的人数:\n");
// int n;
// scanf("%d",&n);
// for(int i=0;i<n;i++)
// { p=(Student*)malloc(sizeof(Student));
// printf("请输入第%d名学生的学号:",++Nstudent);
// scanf("%d",&p->id);
// printf("\n");
// printf("请输入第%d名学生的姓名:",Nstudent);
// scanf("%s",&p->name);
// printf("\n");
// printf("请输入第%d名学生的班级:",p->grade);
// scanf("%s",&p->grade);
// for(int i=0;i<Nsubject;i++)
// {
// printf("请输入%s的成绩:",subject[i]);
// scanf("%lf",&p->score[i]);
// printf("\n");
// }
// p1->next=p;
// p->next=NULL;
// p1=p1->next;
// }
// printf("按任意键继续\n");
// getchar();
// getchar();
//}
/此函数用于修改学生的数据/
void ModifyData(Student *p)
{
printf("请输入学生的新名字\n");
scanf("%s",&p->name);
printf("请输入学生的新学号:\n");
scanf("%d",&p->id);
printf("请输入学生的新年级:\n");
scanf("%d",&p->grade);
printf("请输入学生的性别:\n");
scanf("%d",&p->sex);
printf("请输入C语言的成绩:");
scanf("%lf",&p->C_language);
printf("请输入数学的成绩:");
scanf("%lf",&p->math);
printf("请输入英语的成绩:");
scanf("%lf",&p->enlish);

}
/此函数用于按学生姓名查找/
Student* SearchByName()
{
if(FP==NULL)
{
printf("请打开一个文件,按任意键继续\n");
getchar();
return NULL;
}
char name1[10];
printf("请输入你要查找学生的名字\n" );
scanf("%s",&name1);
Student p;
p=head;
while(p) //当链表为空是结束循环
{
if(p->id==0)
{
p=p->next;
continue;
}
if(!strcmp(p->name,name1)) //比较两个字符数组,如果形同进入循环
{
printf("学号 姓名 性别 年级 C语言 数学 英语 \n");
printf("%-6d ",p->id);
printf("%-3s ",p->name);
printf("%-2s ",p->sex);
printf("%-3s ",p->grade);
printf("%-5.1f ",p->C_language);
printf("%-5.1f ",p->math);
printf("%-5.1f ",p->enlish);
printf("按任意键继续\n");
getchar();
getchar();
return p;
}
p=p->next; //指向链表的下一个节点
}
printf("没有查到这名学生\n");
//printf("按任意键继续\n");
return p;
}
/此函数用于按学生学号查找/
Student
SearchById()
{
if(FP==NULL)
{
printf("请打开一个文件,按任意键继续\n");
getchar();
return NULL;
}
int id1;
printf("请输入你要查找学生的学号\n" );
scanf("%d",&id1 );
Student *p;
p=head;
while(p)
{
if(p->id==0) //学号为零是删除标记
{
p=p->next;
continue;
}
if(p->id==id1) //如果学号相同进入循环
{
printf("学号 姓名 性别 年级 C语言 数学 英语 \n");
printf("%-6d ",p->id);
printf("%-3s ",p->name);
printf("%-2s ",p->sex);
printf("%-3s ",p->grade);
printf("%-5.1f ",p->C_language);
printf("%-5.1f ",p->math);
printf("%-5.1f ",p->enlish);
printf("按任意键继续\n");
getchar();
getchar();
return p;
}
p=p->next;
}
printf("没有查到这名学生\n");
//printf("按任意键继续\n");
return p;
}
void Search()
{
int a;
Student *p;
printf("\t1按学号查找\n");
printf("\t2按姓名查找\n");
scanf("%d",&a);
if(a==1)
p=SearchById(); //调用此函数并返回查找到数据的链表节点地址
else
p=SearchByName(); //调用此函数并返回查找到数据的链表节点地址
printf("按任意键继续\n");
getchar();
getchar();
}
void List()//此函数用列出学生信息
{
if(FP==NULL)
{
printf("请打开文件,按任意键继续\n");
getchar();
getchar();
return ;
}
Student *p;
p=head;
printf("学号 姓名 性别 年级 C语言 数学 英语 \n");
while(p) //当链表为空是结束循环
{
if(p->id==0)
{
p=p->next;
continue;
}

  printf("%-6d  ",p->id);
  printf("%-3s  ",p->name);
  printf("%-2s  ",p->sex);
  printf("%-3s  ",p->grade);
  printf("%-5.1f  ",p->C_language);
  printf("%-5.1f  ",p->math);
  printf("%-5.1f  ",p->enlish);
  printf("\n");
  p=p->next;
}
printf("\n");
printf("按任意键继续\n");
getchar();
getchar();

}
void ModifyStudentData() //此函数用于查找学生并修改此学生的信息
{
int a;
Student *p;
printf("\t1按学号查找\n");
printf("\t2按姓名查找\n");
scanf("%d",&a);
if(a==1)
{
p=SearchById(); //调用此函数并返回查找到数据的链表节点地址
ModifyData(p); //执行此函数,修改此节点上的数据
}
else
{
p=SearchByName(); //调用此函数并返回查找到数据的链表节点地址
ModifyData(p); //执行此函数,修改此节点上的数据
}
printf("按任意键继续\n");
getchar();
getchar();
}
int Menu()//菜单
{
system("cls");
printf("****************************************\n");
printf(" 欢迎使用学生成绩管理系统 \n");
printf("****************************************\n");
printf("===================主菜单===============\n");
printf("***1.输入学生信息 2.显示学生成绩 ***\n");
printf("***3.插入学生信息 4.删除学生信息 ***\n");
printf("***5.查找学生信息 6.修改学生信息 ***\n");
printf("***7.排序学生信息 0.退出 ***\n");

 int choice;
 if(scanf("%d",&choice)!=1||choice<0||choice>10)
 {
     printf("请输入0~10任意一个数字\n");
}
 else
{
 return choice;

}
}
void DeletedData() //此函数用于删除数据
{
Student p;
///p1=(Student
)malloc(sizeof(Student));
printf("\t1按学号查找\n");
printf("\t2按姓名查找\n");
int a;
scanf("%d",&a);
if(a==1)
p=SearchById();
else
p=SearchByName();
if(p==NULL)
{
printf("按任意键继续\n");
getchar();
getchar();
return;
}
printf("是否确认删除?y/n\n");
char b[1];
scanf("%s",&b);
if(b[0]=='y'||b[0]=='Y')
{
p->id=0;
Nstudent--;
}

printf("按任意键继续\n");
getchar();
getchar();
}
int Quit() //此函数用于退出操作;
{
printf("\t\t【退出系统】\n");
system("pause");
exit(0);

}