大一同学录简单编程 帮

问题遇到的现象和发生背景
问题相关代码,请勿粘贴截图
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student
{
    char name[20];
    char sex[10];
    int num;
    int clnum;
    struct Student* next;
};
struct Class
{
    char clname[20];
    int id;
    struct Student* studenthead;//学生头指针
    struct Class* next;
};
void Menu();
//下面的是与学生有关的函数
struct Class* creatnode(struct Class* p);
void Clinput(struct Class* head);
void Initiate(struct Class* p);
void Cldelete(struct Class* head);
struct Class* cldelete1(struct Class* p);
void Cldisplay(struct Class*head);
//下面的是与班级有关的函数
void Display(struct Class*head);
struct Class* Add(struct Class*head);
struct Class* Delete(struct Class*head);
 
 
void Display(struct Class*head)
{
    int count=0;
    int count1=0;
    struct Class *p;
    struct Student *o;
    for (p = head->next;p!=NULL;p=p->next)
    {
        count++;
    }
    //班级总数
    printf("班级总数为%d\n",count);
    if(head->next==NULL)
    {
        printf("还没添加班级呢!\n");
    }
    else
    {
        for(p=head->next;p!=NULL;p=p->next)
        {
            printf("该班名称%s\n",p->clname);
            if(p->studenthead->next!=NULL)
            {
                for(o=p->studenthead->next,count1=0;o!=NULL;o=o->next)//?
                {
                    count1++;
                }
            }
            else
            {
                count1=0;
            }
            
            printf("该班已有同学数%d\n",count1);
        }
    }
    
}
 
struct Class* Add(struct Class* head)
{
 
    struct Class *p,*q;
    if ((q=(struct Class *)malloc(sizeof(struct Class)))==NULL) exit(1);
    printf("请输入班级名称\n");
    scanf("%s",&q->clname);
    printf("请输入班号\n");
    scanf("%d",&q->id);
    for (p = head;p->next!=NULL;p=p->next);//第一个指针无数据域、尾接法、确保每次数据可以接到链表末端
    p->next=q;
    q->next=NULL;
    q->studenthead=NULL;//方便后面判断是否为第一个录入学生
    printf("信息已添加完成!\n");
    return head;
 
 
}
 
struct Class* Delete(struct Class*head)
{
    struct Class *p;
    struct Class *q;
    int number;
    printf("请输入要删除班级的班号\n");
    scanf("%d",&number);
    p=head;
    for(q=NULL;p;q=p,p=p->next)
    {
        if(p->id==number)
        {
            if(q)
            {
                q->next=p->next;
                free(p);
                printf("删除成功\n");
                break;
                
            }
            else//由于我们的头指针不存放数据,这步可写可不写
            {
                head=p->next;
            }
            free(p);
            printf("删除成功\n");
            break;
        }
    }
    printf("班号不存在!\n");
    return head;
 
 
}
 
void Clinput(struct Class* head)
{
    int name;
    struct Class *p;
    printf("请先输入班号。\n");
    scanf("%d",&name);
    for (p=head->next;p!=NULL;p=p->next)
    {
        if(name==p->id)
        {
            p=creatnode(p);
            return ;
        }
    }
    printf("没有这个班号,请先到 2.增加班级。!\n");
}
struct Class* creatnode(struct Class* p)//下面的大写P为学生链表的位置指针,小写p为班级链表的节点指针
{
    if(p->studenthead==NULL)
    {
        Initiate(p);
    }
    struct Student *P,*q;
    if ((q=(struct Student *)malloc(sizeof(struct Student)))==NULL) exit(1);
    printf("请输入学生名字\n");
    scanf("%s",&q->name);
    printf("请输入性别(male or female)\n");
    scanf("%s",&q->sex);
    printf("请输入学号\n");
    scanf("%d",&q->num);
    q->clnum=p->id;
    for (P = p->studenthead;P->next!=NULL;P=P->next);
    P->next=q;
    q->next=NULL;
    printf("学生信息已录入!\n");
    return p;
 
}
void Initiate(struct Class* p)
{
    p->studenthead=(struct Student*)malloc(sizeof(struct Student));
    p->studenthead->next=NULL;
}
void Cldelete(struct Class* head)
{
    int name;
    struct Class *p;
    printf("请先输入该同学所在班号\n");
    scanf("%d",&name);
    for (p = head;p!=NULL;p=p->next)
    {
        if(name==p->id)
        {
            p=cldelete1(p);
            printf("删除成功!");
            return;
        }
    }
    printf("班号不存在!\n");
}
struct Class* cldelete1(struct Class* p)
{
    int num;
    struct Student *P,*q;
    printf("输入要删除同学的学号\n");
    scanf("%d",&num);
    for(P=p->studenthead,q=NULL;P!=NULL;q=P,P=P->next)
    {
        if(P->num==num)
        {
            if(q)
            {
                q->next=P->next;
            }
            else//由于我们的头指针不存放数据,这步可写可不写
            {
                p->studenthead=P->next;
            }
            free(P);
            break;    
            
        }
    }
    return p;
}
void Cldisplay(struct Class*head)
{
    int hao;
    struct Class *p;
    struct Student *q;
    printf("请输入要显示的班级的班号\n");
    scanf("%d",&hao);
    for(p = head;p!=NULL;p=p->next)
    {
        if(p->id==hao)
        {
            if(p->studenthead==NULL)
            {
                printf("该班级还未录入同学!\n");
                return ;
            }
            else
            {
                for(q=p->studenthead->next;q!=NULL;q=q->next)
                {
                    printf("姓名:%s 性别:%s 学号:%d\n",q->name,q->sex,q->num);
                }
                return ;
            }
        }
        
    }
    printf("无此班级!\n");
}
 
 
 
 
 
void Menu()
{
    printf("\n");
    printf("\n");
    printf("\n");
    printf("**************欢迎使用同学录系统(注意所有的第一步都是建立班级先哦)**************");
    printf("\n");
    printf("\n");
    printf("***********  1.显示班级列表(需要先录入同学)   ***********\n");
    printf("***********  2.增加班级    ***********\n");
    printf("***********  3.删除班级    ***********\n");
    printf("***********  4.班级同学录入    ***********\n");
    printf("***********  5.班级同学删除    ***********\n");
    printf("***********  6.显示指定班级同学录    ***********\n");
    printf("***********  7.退出    ***********\n");
}
 
 
 
main()
{
    system("color 02");
    struct Class* Head=(struct Class*)malloc(sizeof(struct Class));
    Head->next=NULL;
    Head->studenthead=NULL;
    int choice;    
    char yes_no;
    do
    {
        Menu();
        printf("请输入指令0-7:\n");
        scanf("%d",&choice);
        switch(choice)
        {
        case 1:Display(Head);
            
            break;
        case 2:Head=Add(Head);
            
            break;
        case 3:Head=Delete(Head);
            
            break;
        case 4:Clinput(Head);
            
            break;
        case 5:Cldelete(Head);
            
            break;
        case 6:Cldisplay(Head);
            
            break;
        case 7:
            printf("感谢使用^-^\n");
            exit(0);
            break;
        default:
            printf("输入错误,请重新输入。\n");
            break;
        }
        printf("是否继续 Y or N?\n");
        do
        {
            scanf("%c",&yes_no);
        }
        while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n');
    }
    while(yes_no=='Y'||yes_no=='y');
    
 
 
    return 0;    
}
 

运行结果及报错内容

void Display(struct Class*head)这一块当学生人数为0时为什么进程会直接终止啊?

我的解答思路和尝试过的方法
我想要达到的结果

void Display(struct Class*head)学生人数为0时,输出该班已有同学数为0.

在Display 方法中,head 节点没有判断是不是有下一个节点,直接赋值给 指针p,所以当学生人数为 0 时,head 是没有下一个节点的,就会出现程序终止。你先判断一下head节点是不是有下一个节点再去赋值就可以解决了。


void Display(struct Class*head)
{
    int count=0;
    int count1=0;
    struct Class *p;
    struct Student *o;
    for (p = head->next;p!=NULL;p=p->next)
    {
        count++;
    }
    //班级总数
    printf("班级总数为%d\n",count);
    if(head->next==NULL)
    {
        printf("还没添加班级呢!\n");
    }
    else
    {
        for(p=head->next;p!=NULL;p=p->next)
        {
            printf("该班名称%s\n",p->clname);
            if(p->studenthead->next!=NULL)
            {
                for(o=p->studenthead->next,count1=0;o!=NULL;o=o->next)//?
                {
                    count1++;
                }
            }
            else
            {
                count1=0;
            }
            
            printf("该班已有同学数%d\n",count1);
        }
    }
    
}

img

单就 void Display(struct Class*head); 函数问题,只要将第54行:if(p->studenthead->next!=NULL) 修改为:if(p->studenthead != NULL) 即可实现学生人数为0时,输出该班已有同学数为0。另几个删除函数做了修改,修改处见注释,供参考:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student
{
    char name[20];
    char sex[10];
    int num;
    int clnum;
    struct Student* next;
};
struct Class
{
    char clname[20];
    int id;
    struct Student* studenthead;//学生头指针
    struct Class* next;
};
void Menu();
//下面的是与学生有关的函数
struct Class* creatnode(struct Class* p);
void Clinput(struct Class* head);
void Initiate(struct Class* p);
void Cldelete(struct Class* head);
void cldelete1(struct Class* p); //struct Class* cldelete1(struct Class* p);
void Cldisplay(struct Class*head);
//下面的是与班级有关的函数
void Display(struct Class* head);
struct Class* Add(struct Class*head);
void Delete(struct Class* head); //struct Class* Delete(struct Class*head);

 
void Display(struct Class*head)
{
    int count=0;
    int count1=0;
    struct Class *p;
    struct Student *o;
    for (p = head->next;p!=NULL;p=p->next)
    {
        count++;
    }
    //班级总数
    printf("班级总数为%d\n",count);
    if(head->next==NULL)
    {
        printf("还没添加班级呢!\n");
    }
    else
    {
        for(p=head->next;p!=NULL;p=p->next)
        {
            printf("该班名称%s\n",p->clname);
            if(p->studenthead != NULL)  //if(p->studenthead->next!=NULL)修改
            {
                for(o=p->studenthead->next,count1=0;o!=NULL;o=o->next)//?
                {
                    count1++;
                }
            }
            else
            {
                count1=0;
            }
            printf("该班已有同学数%d\n",count1);
        }
    }
}
 
struct Class* Add(struct Class* head)
{
 
    struct Class *p,*q;
    if ((q=(struct Class *)malloc(sizeof(struct Class)))==NULL) exit(1);
    printf("请输入班级名称\n");
    scanf("%s",&q->clname);
    printf("请输入班号\n");
    scanf("%d",&q->id);
    for (p = head;p->next!=NULL;p=p->next);//第一个指针无数据域、尾接法、确保每次数据可以接到链表末端
    p->next=q;
    q->next=NULL;
    q->studenthead=NULL;//方便后面判断是否为第一个录入学生
    printf("信息已添加完成!\n");
    return head;
 
 
}

void Delete(struct Class*head)  //struct Class* Delete(struct Class*head)修改
{
    struct Class *p;
    struct Class *q;
    int number;
    printf("请输入要删除班级的班号\n");
    scanf("%d",&number);
                      //p=head;
    for(p=head->next,q=head;p;q=p,p=p->next)//for(q=NULL;p;q=p,p=p->next)
    {
        if(p->id==number)
        {
            //if(q)
            //{
                q->next=p->next;
                free(p);
                printf("删除成功\n");
                break;

            //}
            //else//由于我们的头指针不存放数据,这步可写可不写
            //{
            //    head=p->next;
            //}
            //free(p);
            //printf("删除成功\n");
            //break;
        }
    }
    if(!p)
       printf("班号不存在!\n");
                                 //return head; 修改
}
 
void Clinput(struct Class* head)
{
    int name;
    struct Class *p;
    printf("请先输入班号。\n");
    scanf("%d",&name);
    for (p=head->next;p!=NULL;p=p->next)
    {
        if(name==p->id)
        {
            p=creatnode(p);
            return ;
        }
    }
    printf("没有这个班号,请先到 2.增加班级。!\n");
}
struct Class* creatnode(struct Class* p)//下面的大写P为学生链表的位置指针,小写p为班级链表的节点指针
{
    if(p->studenthead==NULL)
    {
        Initiate(p);
    }
    struct Student *P,*q;
    if ((q=(struct Student *)malloc(sizeof(struct Student)))==NULL) exit(1);
    printf("请输入学生名字\n");
    scanf("%s",&q->name);
    printf("请输入性别(male or female)\n");
    scanf("%s",&q->sex);
    printf("请输入学号\n");
    scanf("%d",&q->num);
    q->clnum=p->id;
    for (P = p->studenthead;P->next!=NULL;P=P->next);
    P->next=q;
    q->next=NULL;
    printf("学生信息已录入!\n");
    return p;
 
}
void Initiate(struct Class* p)
{
    p->studenthead=(struct Student*)malloc(sizeof(struct Student));
    p->studenthead->next=NULL;
}
void Cldelete(struct Class* head)
{
    int name;
    struct Class *p;
    printf("请先输入该同学所在班号\n");
    scanf("%d",&name);
    for (p = head->next;p!=NULL;p=p->next) //for (p = head;p!=NULL;p=p->next)//修改
    {
        if(name==p->id)
        {
            cldelete1(p);
            //p=cldelete1(p);      //修改
            //printf("删除成功!");//修改
            return;
        }
    }
    printf("班号不存在!\n");
}
void cldelete1(struct Class* p) //struct Class* cldelete1(struct Class* p)
{
    int num;
    struct Student *P,*q;
    if(p->studenthead==NULL)    //修改
    {
        printf("该班级还未录入同学!\n");
        return ;
    }
    else{
        printf("输入要删除同学的学号\n");
        scanf("%d",&num);
        for(P=p->studenthead->next,q=p->studenthead;P!=NULL;q=P,P=P->next) //修改
            //for(P=p->studenthead,q=NULL;P!=NULL;q=P,P=P->next)
        {
            if(P->num==num)
            {
               //if(q)          //修改
               //{
                 q->next=P->next;
               //}
               //else//由于我们的头指针不存放数据,这步可写可不写
               //{
               //    p->studenthead=P->next;
               //}
               free(P);
               printf("删除成功!\n"); //修改
               return;//break;         //修改
            }
        }
        printf("未找到学号为:%d 的记录。\n",num);//修改
        return;                       //修改
    }
}
void Cldisplay(struct Class*head)
{
    int hao;
    struct Class *p;
    struct Student *q;
    printf("请输入要显示的班级的班号\n");
    scanf("%d",&hao);
    for(p = head->next;p!=NULL;p=p->next)  // for(p = head;p!=NULL;p=p->next) //修改
    {
        if(p->id==hao)
        {
            if(p->studenthead==NULL)
            {
                printf("该班级还未录入同学!\n");
                return ;
            }
            else
            {
                for(q=p->studenthead->next;q!=NULL;q=q->next)
                {
                    printf("姓名:%s 性别:%s 学号:%d\n",q->name,q->sex,q->num);
                }
                return ;
            }
        }
        
    }
    printf("无此班级!\n");
}
 
 
 
 
 
void Menu()
{
    printf("\n");
    printf("\n");
    printf("\n");
    printf("**************欢迎使用同学录系统(注意所有的第一步都是建立班级先哦)**************");
    printf("\n");
    printf("\n");
    printf("***********  1.显示班级列表(需要先录入同学)   ***********\n");
    printf("***********  2.增加班级    ***********\n");
    printf("***********  3.删除班级    ***********\n");
    printf("***********  4.班级同学录入    ***********\n");
    printf("***********  5.班级同学删除    ***********\n");
    printf("***********  6.显示指定班级同学录    ***********\n");
    printf("***********  7.退出    ***********\n");
}
 
 
 
main()
{
    system("color 02");
    struct Class* Head=(struct Class*)malloc(sizeof(struct Class));
    Head->next=NULL;
    Head->studenthead=NULL;
    int choice;    
    char yes_no;
    do
    {
        Menu();
        printf("请输入指令0-7:\n");
        scanf("%d",&choice);
        switch(choice)
        {
        case 1:Display(Head);
            
            break;
        case 2:Head=Add(Head);
            
            break;
        case 3:Delete(Head);  //Head=Delete(Head);修改
            
            break;
        case 4:Clinput(Head);
            
            break;
        case 5:Cldelete(Head);
            
            break;
        case 6:Cldisplay(Head);
            
            break;
        case 7:
            printf("感谢使用^-^\n");
            exit(0);
            break;
        default:
            printf("输入错误,请重新输入。\n");
            break;
        }
        printf("是否继续 Y or N?\n");
        do
        {
            scanf("%c",&yes_no);
        }
        while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n');
    }
    while(yes_no=='Y'||yes_no=='y');
    
 
 
    return 0;    
}

因为班级数为零的时候,不会进入到下面这个for循环当中

for(p=head->next;p!=NULL;p=p->next)
        {
            printf("该班名称%s\n",p->clname);
            if(p->studenthead->next!=NULL)
            {
                for(o=p->studenthead->next,count1=0;o!=NULL;o=o->next)//?
                {
                    count1++;
                }
            }
            else
            {
                count1=0;
            }
            
            printf("该班已有同学数%d\n",count1);
        }