鱼C论坛

 找回密码
 立即注册
查看: 1785|回复: 9

记录或删除学生成绩的<链表>,但是不知道哪里出错了

[复制链接]
发表于 2020-8-3 16:58:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
/***********************************************************
************              动态记录学生成绩的链表                ************
************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

#define LEN sizeof(struct student)        //student 结构大小

struct student* creat();                        //创建链表(函数)

void print(struct student* head);        //打印链表(函数)

void del(struct student* head, int dnum);//删除链表函数

void ask(int i);

struct student
{
        int num;
        float score;
        struct student* next;
};

int n;                                                                //记录存放多少组数据

int main()
{
        int i,dnum;
        i = 0;
        struct student* stu;

        stu = creat();
        print(stu);

        printf("\n\n");

        while (1)
        {
                ask(i);
                scanf("%d", &i);

                if (i == 1)
                {
                        printf("\nPlease enter the number of the student:\n\tnum: ");
                        scanf_s("%d", &dnum);

                        del(stu, dnum);

                        print(stu);
                }
                else break;
        }
        system("pause");


}

struct student *creat()
{
        struct student* head;                                        //声明头部节点head
        struct student* p1, * p2;                                //声明p1 p2,两个节点

        p1 = p2 = (struct student*)malloc(LEN);        //LEN是student结构大小

        printf("Please enter the num:");
        scanf_s("%d", &p1->num);

        printf("Please enter the score:");
        scanf_s("%f", &p1->score);

        head = NULL;                                                //head归零(不指向任意东西)
        n = 0;

        while (/*0!=*/p1->num)                                //p1不为零则循环,当输入0时停止循环
        {
                n++;
                if (1 == n)
                {
                        head = p1;
                }
                else
                {
                        p2->next = p1;
                }
                p2 = p1;
                 
                p1 = (struct student*)malloc(LEN);

                printf("\nPlease enter the num :");
                scanf_s("%d", &p1->num);

                printf("Please enter the score:");
                scanf_s("%f", &p1->score);
        }

        p2->next = NULL;

        return head;
}

void print(struct student* head)                        /*输出链表内容*/
{
        struct student* p;

        printf("\n There are %d records!\n\n", n);

        p = head;
        if (/*NULL!+*/head)
        {
                do
                {
                        printf("学号为 < %d > 的成绩是:%f\n", p->num, p->score);
                        p = p->next;
                } while (/*NULL!=*/p);
        }
}

void del(struct student *head,int dnum)                        //删除链表函数
{
        struct student * p1, * p2;
        int a = 0;
        if (head == NULL) { printf("This is a empty form"); }
        else
        {
                p1 = head;
                p2 = NULL;
                while (dnum != p1->num && p1!=NULL)
                {
                        p2 = p1;
                        p1 = p1->next;
                        a++;
                }
                if (p1!=NULL)
                {
                        if (p1 == head)
                        {
                                head = p1->next;
                        }
                        else
                        {
                                p2->next = p1->next;
                        }
                        printf("\nThe data of < %d > had been deleted!\n\n",dnum);
                        n = n - 1;
                }
                else if(p1==NULL)
                {
                        printf("\nNo student with  number %d was found.\n\n", dnum);
                }
        }
}

void ask(int i)
{
        printf("Do you want to delete a data of student?\nif you want,please enter int'1',else enter int'0'\n\n||--->Enter:");
}
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-3 17:54:00 | 显示全部楼层
本帖最后由 SHRS23 于 2020-8-3 17:55 编辑

  1. /***********************************************************
  2. ************              动态记录学生成绩的链表                ************
  3. ************************************************************/

  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include<malloc.h>

  7. #define LEN sizeof(struct student)        //student 结构大小

  8. struct student *creat();                        //创建链表(函数)

  9. void print(struct student *head);        //打印链表(函数)

  10. void del(struct student *head, int dnum);//删除链表函数

  11. void ask(int i);

  12. struct student
  13. {
  14.     int num;
  15.     float score;
  16.     struct student *next;
  17. };

  18. int n;                                                                //记录存放多少组数据

  19. int main()
  20. {
  21.     int i, dnum;
  22.     i = 0;
  23.     struct student *stu;
  24.     stu = creat();
  25.     print(stu);
  26.     printf("\n\n");

  27.     while(1)
  28.     {
  29.         ask(i);
  30.         scanf("%d", &i);

  31.         if(i == 1)
  32.         {
  33.             printf("\nPlease enter the number of the student:\n\tnum: ");
  34.             scanf("%d", &dnum);
  35.             del(stu, dnum);
  36.             print(stu);
  37.         }
  38.         else
  39.         {
  40.             break;
  41.         }
  42.     }

  43.     system("pause");
  44. }

  45. struct student *creat()
  46. {
  47.     struct student *head;                                        //声明头部节点head
  48.     struct student *p1, * p2;                                //声明p1 p2,两个节点
  49.     p1 = p2 = (struct student *)malloc(LEN);       //LEN是student结构大小
  50.     printf("Please enter the num:");
  51.     scanf("%d", &p1->num);
  52.     printf("Please enter the score:");
  53.     scanf("%f", &p1->score);
  54.     head = NULL;                                                //head归零(不指向任意东西)
  55.     n = 0;

  56.     while(/*0!=*/p1->num)                                 //p1不为零则循环,当输入0时停止循环
  57.     {
  58.         n++;

  59.         if(1 == n)
  60.         {
  61.             head = p1;
  62.         }
  63.         else
  64.         {
  65.             p2->next = p1;
  66.         }

  67.         p2 = p1;
  68.         p1 = (struct student *)malloc(LEN);
  69.         printf("\nPlease enter the num :");
  70.         scanf("%d", &p1->num);
  71.         printf("Please enter the score:");
  72.         scanf("%f", &p1->score);
  73.     }

  74.     p2->next = NULL;
  75.     return head;
  76. }

  77. void print(struct student *head)                        /*输出链表内容*/
  78. {
  79.     struct student *p;
  80.     printf("\n There are %d records!\n\n", n);
  81.     p = head;

  82.     if(/*NULL!+*/head)
  83.     {
  84.         do
  85.         {
  86.             printf("学号为 < %d > 的成绩是:%f\n", p->num, p->score);
  87.             p = p->next;
  88.         }
  89.         while(/*NULL!=*/p);
  90.     }
  91. }

  92. void del(struct student *head, int dnum)                       //删除链表函数
  93. {
  94.     struct student *p1, * p2;
  95.     int a = 0;

  96.     if(head == NULL)
  97.     {
  98.         printf("This is a empty form");
  99.     }
  100.     else
  101.     {
  102.         p1 = head;
  103.         p2 = NULL;

  104.         while(dnum != p1->num && p1 != NULL)
  105.         {
  106.             p2 = p1;
  107.             p1 = p1->next;
  108.             a++;
  109.         }

  110.         if(p1 != NULL)
  111.         {
  112.             if(p1 == head)
  113.             {
  114.                 head = p1->next;
  115.             }
  116.             else
  117.             {
  118.                 p2->next = p1->next;
  119.             }

  120.             printf("\nThe data of < %d > had been deleted!\n\n", dnum);
  121.             n = n - 1;
  122.         }
  123.         else if(p1 == NULL)
  124.         {
  125.             printf("\nNo student with  number %d was found.\n\n", dnum);
  126.         }
  127.     }
  128. }

  129. void ask(int i)
  130. {
  131.     printf("Do you want to delete a data of student?\nif you want,please enter int'1',else enter int'0'\n\n||--->Enter:");
  132. }
复制代码


做了个简单的小测试,程序本身问题不大
我想问一下你的调试运行环境是是什么
如果你用的visual studio并且你清楚你为什么要用scanf_s,那么修改方法就是把scanf_s缺少的参数补上;
如果你用的不是VS或者你不知道scanf_s是什么,那就像我上面的程序一样,把所有的scanf_s替换成scanf。


以下内容来自百度百科:

ANSI C中没有scanf_s(),只有scanf(),scanf()在读取时不检查边界,所以可能会造成内存访问越界,例如分配了5字节的空间但是读入了10字节
char buf[5]={'\0'};
scanf("%s", buf);
如果输入1234567890,后面的部分会被写到别的空间上去。
以上代码如果用scanf_s,第二行应改为scanf_s("%s",buf,5),表示最多读取5-1个字符,因为buf[4]要放'\0'
scanf_s最后一个参数是缓冲区的大小,表示最多读取n-1个字符.
vc++2005/2008中提供了scanf_s(),在最新的VS2015中也提供了scanf_s()。在调用时,必须提供一个数字以表明最多读取多少位字符。
3.读取单个字符也需要限定长度:scanf_s("%c,%c",&c1,1,&c2,1);而不能写成scanf_s("%c,%c",&c1, &c2,1, 1);否则编译器会报错
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-3 17:58:29 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-3 18:14:10 | 显示全部楼层
本帖最后由 baige 于 2020-8-3 18:45 编辑

删除那里需要用二级指针, 删除时对学号的判断以及链表是否为空有bug,当p1==NULL,p1->num是未知的,产生bug;
https://blog.csdn.net/qq_39032310/article/details/81746742

  1. #include<stdio.h>
  2. #include<stdlib.h>

  3. #define LEN sizeof(struct student)//student 结构大小

  4. struct student* creat();//创建链表(函数)
  5. void print(struct student* head);//打印链表(函数)
  6. void del(struct student** head, int dnum);//删除链表函数
  7. void ask(int i);// 是否需要删除结点

  8. struct student
  9. {
  10.         int num;
  11.         float score;
  12.         struct student* next;
  13. };

  14. int n;//记录存放多少组数据

  15. int main()
  16. {
  17.         int i = 0,dnum;
  18.         struct student* stu;

  19.         stu = creat();
  20.         print(stu);

  21.         printf("\n\n");

  22.         while (1)
  23.         {
  24.                 ask(i);
  25.                 scanf("%d", &i);// 输入i
  26.                 if (i == 1) // 当i==1需要删除结点
  27.                 {
  28.                         printf("\nPlease enter the number of the student:\n\tnum: ");
  29.                         scanf("%d", &dnum); //  
  30.                         
  31.                         del(&stu, dnum);
  32.                         print(stu);
  33.                 }
  34.                 else break;
  35.         }
  36.         system("pause");
  37.         return 0;
  38. }

  39. struct student *creat()
  40. {
  41.         struct student* head;//声明头部节点head
  42.         struct student* p1, * p2;//声明p1 p2,两个节点
  43.         
  44.         p1 = p2 = (struct student*)malloc(LEN);        //LEN是student结构大小
  45.         printf("Please enter the num:");
  46.         scanf("%d", &p1->num);
  47.         head = NULL;
  48.         p1->next = NULL; // 初始化p1指针域
  49.         printf("Please enter the score:");
  50.         scanf("%f", &p1->score);
  51.         n = 0;
  52.    
  53.         while (p1->num)                                //p1不为零则循环,当输入0时停止循环
  54.         {
  55.                 n++;
  56.                 if (1 == n)
  57.                 {
  58.                         head = p1;
  59.                 }
  60.                 else
  61.                 {
  62.                         p2->next = p1;
  63.                 }
  64.                 p2 = p1;
  65.                 p1 = (struct student*)malloc(LEN);

  66.                 printf("\nPlease enter the num :");
  67.                 scanf("%d", &p1->num);
  68.                 printf("Please enter the score:");
  69.                 scanf("%f", &p1->score);
  70.             }

  71.         p2->next = NULL;

  72.         return head;
  73. }

  74. void print(struct student* head)                        /*输出链表内容*/
  75. {
  76.         struct student* p = head;
  77.         printf("\n There are %d records!\n\n", n);

  78.         if(head)
  79.         {
  80.                 do
  81.                 {
  82.                         printf("学号为 < %d > 的成绩是:%f\n", p->num, p->score);
  83.                         p = p->next;
  84.                 } while (p);
  85.         }
  86. }

  87. void del(struct student **head,int dnum)                        //删除链表函数
  88. {
  89.         struct student *p1, *p2;
  90.         int a = 0;
  91.         if (*head == NULL)
  92.         {
  93.                 printf("This is a empty form");
  94.         }
  95.         else
  96.         {
  97.                 p1 = *head;
  98.                 p2 = NULL;
  99.                 while (dnum != p1->num) // 当p1->num == dumn或 p1 == NULL 退出循环 ,当p1==NULL时,p1->num位置,会导致程序发生未知错误
  100.                 {
  101.                         p2 = p1;
  102.                         p1 = p1->next;
  103.                         a++;
  104.                         if(p1==NULL)break;// 所以我把p1==NULL退出循环写到这里
  105.                 }
  106.                 if (p1!=NULL)
  107.                 {
  108.                         if (p1 == *head)
  109.                         {
  110.                                 *head = p1->next;
  111.                         }
  112.                         else
  113.                         {
  114.                                 p2->next = p1->next;
  115.                         }
  116.                         printf("\nThe data of < %d > had been deleted!\n\n",dnum);
  117.                         n = n - 1;
  118.                 }
  119.                 else
  120.                 {
  121.                         printf("\nNo student with  number %d was found.\n\n", dnum);
  122.                 }
  123.         }
  124. }

  125. void ask(int i)
  126. {
  127.         printf("Do you want to delete a data of student?\nif you want,please enter int'1',else enter int'0'\n\n||--->Enter:");
  128. }
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-3 18:49:25 | 显示全部楼层
本帖最后由 baige 于 2020-8-4 08:20 编辑


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-3 18:56:50 | 显示全部楼层
baige 发表于 2020-8-3 18:49
删除那里用2级指针,以及对于删除时判断p1->num和p1==NULL会产生bug,当p1==NULL,p1->num是未知的;

把scanf改回去就可以了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-3 19:15:54 | 显示全部楼层
本帖最后由 baige 于 2020-8-3 19:40 编辑

你的代码,已修改
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<malloc.h>

  4. #define LEN sizeof(struct student)        //student 结构大小

  5. struct student* creat();                        //创建链表(函数)

  6. void print(struct student* head);        //打印链表(函数)

  7. void del(struct student** head, int dnum);//删除链表函数

  8. void ask(int i);

  9. struct student
  10. {
  11.          int num;
  12.          float score;
  13.          struct student* next;
  14. };

  15. int n;                                                                //记录存放多少组数据

  16. int main()
  17. {
  18.          int i,dnum;
  19.          i = 0;
  20.          struct student* stu;

  21.          stu = creat();
  22.          print(stu);

  23.          printf("\n\n");

  24.          while (1)
  25.          {
  26.                  ask(i);
  27.                  scanf("%d", &i);

  28.                  if (i == 1)
  29.                  {
  30.                          printf("\nPlease enter the number of the student:\n\tnum: ");
  31.                          scanf("%d", &dnum);

  32.                          del(&stu, dnum);

  33.                          print(stu);
  34.                  }
  35.                  else break;
  36.          }
  37.          system("pause");


  38. }

  39. struct student *creat()
  40. {
  41.          struct student* head;                                        //声明头部节点head
  42.          struct student* p1, * p2;                                //声明p1 p2,两个节点

  43.         p1 = p2 = (struct student*)malloc(LEN);        //LEN是student结构大小

  44.         printf("Please enter the num:");
  45.          scanf("%d", &p1->num);

  46.          printf("Please enter the score:");
  47.          scanf("%f", &p1->score);

  48.          head = NULL;                                                //head归零(不指向任意东西)
  49.         n = 0;

  50.          while (/*0!=*/p1->num)                                //p1不为零则循环,当输入0时停止循环
  51.         {
  52.                  n++;
  53.                  if (1 == n)
  54.                  {
  55.                          head = p1;
  56.                  }
  57.                  else
  58.                  {
  59.                          p2->next = p1;
  60.                  }
  61.                  p2 = p1;
  62.                   
  63.                  p1 = (struct student*)malloc(LEN);

  64.                  printf("\nPlease enter the num :");
  65.                  scanf("%d", &p1->num);

  66.                  printf("Please enter the score:");
  67.                  scanf("%f", &p1->score);
  68.          }

  69.          p2->next = NULL;

  70.          return head;
  71. }

  72. void print(struct student* head)                        /*输出链表内容*/
  73. {
  74.          struct student* p;

  75.          printf("\n There are %d records!\n\n", n);

  76.          p = head;
  77.          if (/*NULL!+*/head)
  78.          {
  79.                  do
  80.                  {
  81.                          printf("学号为 < %d > 的成绩是:%f\n", p->num, p->score);
  82.                          p = p->next;
  83.                  } while (/*NULL!=*/p);
  84.          }
  85. }

  86. void del(struct student **head,int dnum)                        //删除链表函数
  87. {
  88.          struct student * p1, * p2;
  89.          int a = 0;
  90.          if (*head == NULL) { printf("This is a empty form"); }
  91.          else
  92.          {
  93.                  p1 = *head;
  94.                  p2 = NULL;
  95.                  while (p1!=NULL&&dnum != p1->num)//短路
  96.                  {
  97.                          p2 = p1;
  98.                          p1 = p1->next;
  99.                          a++;
  100.                  }
  101.                  if (p1!=NULL)
  102.                  {
  103.                          if (p1 == *head)
  104.                          {
  105.                                  *head = p1->next;
  106.                          }
  107.                          else
  108.                          {
  109.                                  p2->next = p1->next;
  110.                          }
  111.                          printf("\nThe data of < %d > had been deleted!\n\n",dnum);
  112.                          n = n - 1;
  113.                  }
  114.                  else if(p1==NULL)
  115.                  {
  116.                          printf("\nNo student with  number %d was found.\n\n", dnum);
  117.                  }
  118.          }
  119. }

  120. void ask(int i)
  121. {
  122.          printf("Do you want to delete a data of student?\nif you want,please enter int'1',else enter int'0'\n\n||--->Enter:");
  123. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-4 11:43:08 | 显示全部楼层
baige 发表于 2020-8-3 19:15
你的代码,已修改

感谢感谢。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-4 11:43:58 | 显示全部楼层
可以的话给个最佳,谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-3 02:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表