鱼C论坛

 找回密码
 立即注册
查看: 1994|回复: 14

[已解决]求帮助,非常着急,大佬们,有关链表与文件的

[复制链接]
发表于 2018-9-6 19:38:35 | 显示全部楼层 |阅读模式
66鱼币
[
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. struct Student
  5. {
  6.         char name[20];
  7.         long long int numb;
  8.         struct Student * pNext;
  9. } ;
  10. struct Student_1
  11. {
  12.         char name[20];
  13.         long long int numb;
  14. } ;
  15. int n;

  16. struct Student * create()
  17. {
  18.         FILE * fp;
  19.         if((fp=fopen("student","wb"))==NULL)
  20.         {
  21.                 printf("cannot open file\n");
  22.                 exit(0);
  23.         }
  24.         struct Student *head=NULL,*pEnd,*pNew,*p;
  25.         n=0;
  26.         char ch;
  27.         pEnd=pNew=(struct Student*)malloc(sizeof(struct Student));
  28.         do
  29.         {
  30.            printf("请输入学生姓名:\n");
  31.            scanf("%s",pNew->name);
  32.            getchar();
  33.            printf("请输入学生学号:\n");
  34.            scanf("%lld",&pNew->numb );
  35.            getchar();
  36.            n++;
  37.            if(n==1)
  38.            {
  39.                 pNew->pNext=head;
  40.                 head=pNew;
  41.            }
  42.            else
  43.            {
  44.                 pNew->pNext=NULL;
  45.                 pEnd->pNext=pNew;
  46.                 pEnd=pNew;
  47.             }   
  48.             
  49.             printf("是否继续录入(y/n):\n");
  50.             ch=getchar();
  51.             getchar();
  52.             if(ch=='y')
  53.                pNew=(struct Student*)malloc(sizeof(struct Student));
  54.     }while(ch=='y');
  55.     p=head;
  56.     while(p!=NULL)
  57.     {  
  58.             if(fwrite(p,sizeof(struct Student_1),1,fp)!=1)
  59.             {
  60.                     printf("录入出错!\n");
  61.                 }
  62.                 p=p->pNext;
  63.         }
  64.         fclose(fp);       
  65.         return head;
  66. }
  67. void print(struct Student* head)
  68. {
  69.         struct Student *p;
  70.         p=head;
  71.         printf("姓名\t\t学号\n");
  72.         while(p!=NULL)
  73.         {
  74.                 printf("%s\t\t%lld\n",p->name,p->numb);
  75.                 p=p->pNext;
  76.         }
  77. }



  78. int main()
  79. {
  80.         struct Student* head;
  81.         head=create();
  82.         system("cls");
  83.         print(head);
  84.         return 0;
  85. }
复制代码

这是用c写的用链表形式将数据以二进制形式写入文件;
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. struct Student
  5. {
  6.         char name[20];
  7.         long long int numb;
  8.         struct Student * pNext;
  9. } ;
  10. struct Student_1
  11. {
  12.         char name[20];
  13.         long long int numb;
  14. } ;
  15. int n;

  16. struct Student * fprint()
  17. {
  18.         FILE *fp;
  19.         struct Student *head=NULL,*pnew,*pend;
  20.         if((fp=fopen("student","rb"))==NULL)
  21.         {
  22.                 printf("不能打开文件!");
  23.                 exit(0);
  24.          }
  25.          n=0;
  26.          while(!feof(fp))
  27.          {
  28.                  n++;     
  29.                  pnew=(struct Student*)malloc(sizeof(struct Student));
  30.                  fread(pnew,sizeof(struct Student_1),1,fp);
  31.                  if(n==1)
  32.                  {
  33.                          pnew->pNext=head;
  34.                          head=pnew;
  35.                          pend=pnew;
  36.                  }
  37.                  else
  38.                  {
  39.                          pend->pNext=pnew;
  40.                          pend=pnew;
  41.                          pnew->pNext=NULL;
  42.                  }
  43.          }
  44.          return head;
  45. }



  46. void print(struct Student* head)
  47. {
  48.         struct Student *p;
  49.         p=head;
  50.         printf("姓名\t\t学号\n");
  51.         while(p!=NULL)
  52.         {
  53.                 printf("%s\t\t%lld\n",p->name,p->numb);
  54.                 p=p->pNext;
  55.          
  56.         }
  57. }



  58. int main()
  59. {
  60.         struct Student* head;
  61.         head=fprint();
  62.        
  63.         print(head);
  64.         return 0;
  65. }
复制代码

这是对应上面的,可以将数据从文件中读取,但是问题是我录入一组数据,输出两组数据(第二组是乱码),每一次输出都比输入数据多一组?这问题出在哪里了?附上图
最佳答案
2018-9-6 19:38:36
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. struct Student
  5. {
  6.         char name[20];
  7.         long long int numb;
  8.         struct Student *pNext;
  9. };
  10. struct Student_1
  11. {
  12.         char name[20];
  13.         long long int numb;
  14. };
  15. int n;

  16. struct Student *fprint()
  17. {
  18.         FILE *fp;
  19.         struct Student *head = NULL, *pnew, *pend;
  20.         if((fp = fopen("student", "rb")) == NULL)
  21.         {
  22.                 printf("不能打开文件!");
  23.                 exit(0);
  24.         }

  25.         n = 0;
  26.         /*while(!feof(fp))
  27.         {
  28.                 n++;
  29.                 pnew = (struct Student*)malloc(sizeof(struct Student));
  30.                 fread(pnew, sizeof(struct Student_1), 1, fp);
  31.                 if(n == 1)
  32.                 {
  33.                         pnew->pNext = head;
  34.                         head = pnew;
  35.                         pend = pnew;
  36.                 }
  37.                 else
  38.                 {
  39.                         pend->pNext = pnew;
  40.                         pend = pnew;
  41.                         pnew->pNext = NULL;
  42.                 }
  43.         }*/
  44.         while(1)
  45.         {
  46.                 n++;
  47.                 pnew = (struct Student*)malloc(sizeof(struct Student));
  48.                 fread(pnew, sizeof(struct Student_1), 1, fp);
  49.                 if(feof(fp))
  50.                 {
  51.                         free(pnew);
  52.                         break;
  53.                 }

  54.                 if(n == 1)
  55.                 {
  56.                         pnew->pNext = head;
  57.                         head = pnew;
  58.                         pend = pnew;
  59.                 }
  60.                 else
  61.                 {
  62.                         pend->pNext = pnew;
  63.                         pend = pnew;
  64.                         pnew->pNext = NULL;
  65.                 }
  66.         }

  67.         return head;
  68. }

  69. void print(struct Student* head)
  70. {
  71.         struct Student *p;
  72.         p = head;
  73.         printf("姓名\t\t学号\n");
  74.         while(p != NULL)
  75.         {
  76.                 printf("%s\t\t%lld\n", p->name, p->numb);
  77.                 p = p->pNext;

  78.         }
  79. }

  80. int main(void)
  81. {
  82.         struct Student* head;
  83.         head = fprint();
  84.         print(head);
  85.         return 0;
  86. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 19:38:36 | 显示全部楼层    本楼为最佳答案   
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. struct Student
  5. {
  6.         char name[20];
  7.         long long int numb;
  8.         struct Student *pNext;
  9. };
  10. struct Student_1
  11. {
  12.         char name[20];
  13.         long long int numb;
  14. };
  15. int n;

  16. struct Student *fprint()
  17. {
  18.         FILE *fp;
  19.         struct Student *head = NULL, *pnew, *pend;
  20.         if((fp = fopen("student", "rb")) == NULL)
  21.         {
  22.                 printf("不能打开文件!");
  23.                 exit(0);
  24.         }

  25.         n = 0;
  26.         /*while(!feof(fp))
  27.         {
  28.                 n++;
  29.                 pnew = (struct Student*)malloc(sizeof(struct Student));
  30.                 fread(pnew, sizeof(struct Student_1), 1, fp);
  31.                 if(n == 1)
  32.                 {
  33.                         pnew->pNext = head;
  34.                         head = pnew;
  35.                         pend = pnew;
  36.                 }
  37.                 else
  38.                 {
  39.                         pend->pNext = pnew;
  40.                         pend = pnew;
  41.                         pnew->pNext = NULL;
  42.                 }
  43.         }*/
  44.         while(1)
  45.         {
  46.                 n++;
  47.                 pnew = (struct Student*)malloc(sizeof(struct Student));
  48.                 fread(pnew, sizeof(struct Student_1), 1, fp);
  49.                 if(feof(fp))
  50.                 {
  51.                         free(pnew);
  52.                         break;
  53.                 }

  54.                 if(n == 1)
  55.                 {
  56.                         pnew->pNext = head;
  57.                         head = pnew;
  58.                         pend = pnew;
  59.                 }
  60.                 else
  61.                 {
  62.                         pend->pNext = pnew;
  63.                         pend = pnew;
  64.                         pnew->pNext = NULL;
  65.                 }
  66.         }

  67.         return head;
  68. }

  69. void print(struct Student* head)
  70. {
  71.         struct Student *p;
  72.         p = head;
  73.         printf("姓名\t\t学号\n");
  74.         while(p != NULL)
  75.         {
  76.                 printf("%s\t\t%lld\n", p->name, p->numb);
  77.                 p = p->pNext;

  78.         }
  79. }

  80. int main(void)
  81. {
  82.         struct Student* head;
  83.         head = fprint();
  84.         print(head);
  85.         return 0;
  86. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-9-6 19:40:15 | 显示全部楼层
1.png 2.png 3.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 19:58:00 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 21:35:30 | 显示全部楼层
本帖最后由 理想小青年 于 2018-9-6 21:37 编辑

大体判断一下,错误原因,结构体大小不一样,Student是40字节大小,Student_1是32字节大小,所以
1、pnew = (struct Student*)malloc(sizeof(struct Student));
     fread(pnew, sizeof(struct Student_1), 1, fp);
上面两句是错误的,读取块大小是32字节,应该是40个字节。
两个结构体大小不一样, 应该这样写:
(1)fread(pnew, sizeof(struct Student), 1, fp);
(2)fwrite(p,sizeof(struct Student),1,fp);
2、打开文件应该是 "rb+","wb+"  把加号写上。
3、 养成关闭文件习惯fclose();
然后在尝试看一看
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-9-6 21:43:36 From FishC Mobile | 显示全部楼层
理想小青年 发表于 2018-9-6 21:35
大体判断一下,错误原因,结构体大小不一样,Student是40字节大小,Student_1是32字节大小,所以
1、pnew  ...

结构体不一样是因为我要往文件储存时不想把指针存进去,因为这样完全没必要,到时候还是要给指针赋值的,之前我就只定义了一个结构体,但是问题依然还有,关闭文件会修改的,谢谢您(*°°)=3
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 21:47:32 | 显示全部楼层
...
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-9-6 23:29:22 | 显示全部楼层

666,厉害,PS:不过我想知道我的为什么不可以呢?怎么会多出一组呢?不是到文件尾就结束循环了吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 23:49:05 | 显示全部楼层
易晓外 发表于 2018-9-6 23:29
666,厉害,PS:不过我想知道我的为什么不可以呢?怎么会多出一组呢?不是到文件尾就结束循环了吗?

自己百度 feof函数
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 13:23:08 | 显示全部楼层
易晓外 发表于 2018-9-6 23:29
666,厉害,PS:不过我想知道我的为什么不可以呢?怎么会多出一组呢?不是到文件尾就结束循环了吗?

*head = NULL
不是很清楚为什么哥哥要这样写
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 13:26:16 | 显示全部楼层
本帖最后由 claws0n 于 2018-9-7 13:29 编辑
人造人 发表于 2018-9-6 23:49
自己百度 feof函数


写入
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. struct Student
  5. {
  6.     char name[20];
  7.     long long int numb;
  8.     struct Student* pNext;
  9. } ;

  10. struct Student_1
  11. {
  12.     char name[20];
  13.     long long int numb;
  14. } ;

  15. struct Student * create()
  16. {
  17.     FILE * fp;
  18.     if((fp=fopen("student.txt","wb")) == NULL)
  19.     {
  20.             printf("cannot open file\n");
  21.             exit(0);
  22.     }
  23.    
  24.     struct Student *head, *pNew, *p;
  25.         head->pNext = NULL;
  26.     char ch;
  27.    
  28.     pNew = (struct Student*)malloc(sizeof(struct Student));
  29.    
  30.     p = head;        //索引指针
  31.     while( p->pNext )                //尾插法
  32.         p = p->pNext;
  33.     do
  34.     {
  35.         printf("请输入学生姓名:\n");
  36.         scanf("%s", pNew->name);
  37.         getchar();
  38.         printf("请输入学生学号:\n");
  39.         scanf("%lld", &pNew->numb);
  40.         getchar();
  41.                
  42.         p->pNext = pNew;
  43.         pNew->pNext = NULL;
  44.         p = p->pNext;
  45.         
  46.         printf("是否继续录入(y/n):\n");
  47.         ch = getchar();
  48.         getchar();
  49.         if(ch == 'y'|| ch == 'Y') //把大写也纳入
  50.            pNew = (struct Student*)malloc(sizeof(struct Student));
  51.            
  52.     }while(ch == 'y'|| ch == 'Y'); //把大写也纳入
  53.    
  54.     p = head->pNext;
  55.     while( p )
  56.     {  
  57.         if(fwrite(p, sizeof(struct Student_1), 1, fp) != 1)
  58.         {
  59.             printf("录入出错!\n");
  60.         }
  61.         p = p->pNext;
  62.     }
  63.     fclose(fp);
  64.     return head;
  65. }

  66. void print(struct Student* head)
  67. {
  68.     struct Student *p;
  69.     p = head->pNext;
  70.     printf("姓名\t\t学号\n");
  71.     while( p )
  72.     {
  73.         printf("%s\t\t%lld\n", p->name, p->numb);
  74.         p = p->pNext;
  75.     }
  76. }


  77. int main()
  78. {
  79.     struct Student* head;
  80.     head = create();
  81.     system("cls");
  82.     print(head);
  83.     return 0;
  84. }
复制代码
读取
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. struct Student
  5. {
  6.     char name[20];
  7.     long long int numb;
  8.     struct Student * pNext;
  9. } ;

  10. struct Student_1
  11. {
  12.     char name[20];
  13.     long long int numb;
  14. } ;


  15. struct Student * fprint()
  16. {
  17. FILE *fp;
  18. struct Student *head, *pNew, *p;
  19.        
  20. if((fp = fopen("student.txt","rb")) == NULL)
  21. {
  22.         printf("不能打开文件!");
  23.         exit(0);
  24. }
  25.        
  26. head->pNext = NULL;
  27. p = head;
  28.        
  29. while(!feof(fp))
  30. {
  31.         pNew = (struct Student*)malloc(sizeof(struct Student));
  32.         fread(pNew, sizeof(struct Student_1), 1, fp);
  33.                
  34.         p->pNext = pNew;
  35.         pNew->pNext = NULL;
  36.         p = p->pNext;
  37. }
  38. return head;
  39. }



  40. void print(struct Student* head)
  41. {
  42.     struct Student *p;
  43.     p = head->pNext;
  44.     printf("姓名\t\t学号\n");
  45.     while( p->pNext )
  46.     {
  47.         printf("%s\t\t%lld\n", p->name, p->numb);
  48.         p = p->pNext;
  49.     }
  50. }

  51. int main()
  52. {
  53.     struct Student* head;
  54.     head = fprint();
  55.     printf("reading...\n");
  56.     print(head);
  57.     return 0;
  58. }
复制代码

*head = NULL 的问题吧?虽然浪费了一个空间,但这样写不是更好吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 17:19:55 | 显示全部楼层
claws0n 发表于 2018-9-7 13:26
写入读取
*head = NULL 的问题吧?虽然浪费了一个空间,但这样写不是更好吗?

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

使用道具 举报

发表于 2018-9-7 18:30:41 | 显示全部楼层

问题应该是出至于头指针。我把插入的方法稍微改了一下,就不会有问题了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 21:08:10 | 显示全部楼层
claws0n 发表于 2018-9-7 18:30
问题应该是出至于头指针。我把插入的方法稍微改了一下,就不会有问题了

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

使用道具 举报

 楼主| 发表于 2018-9-7 21:27:19 | 显示全部楼层
“C”语言的“feof()”函数和数据库中“eof()”函数的运作是完全不同的。数据库中“eof()”函数读取当前指针的位置,“C”语言的“feof()”函数返回的是最后一次“读操作的内容”。多年来把“位置和内容”相混,从而造成了对这一概念的似是而非。

那么,位置和内容到底有何不同呢?举个简单的例子,比如有人说“你走到火车的最后一节车箱”这就是位置。而如果说“请你一直向后走,摸到铁轨结束”这就是内容。也就是说用内容来判断会“多走一节”。这就是完全依赖于“while(!feof(FP)){...}”进行文件复制时,目标文档总会比源文档“多出一些”的原因。
这是错误原因!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-10 02:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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