user-0 提问: 电影院售票系统 c语言制作 请教 文件读取 写入问题

回复:
user: user-1
content: 可以结贴了，给我点分吧

user: user-1
content: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<windows.h>  void new_mv(); void save_mv(); int judge(); void read_data();// void show();// void menu_print(); void guanli_menu(); void guanli(); void youke_menu(); void youke(); void buy_mv(); void leave_mv(); void add_mv();  typedef struct movie {     char name[20];     int money;     int ticket;     struct movie *next; }mv; mv * head = NULL;  int main() {     int k = 1;     int switch_count=0;     do     {         menu_print();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)//分支里面的函数用处理过后的函数，用 judge与其他函数组合出来的函数。         {         case 0:             k = 0;             break;         case 1:             system("cls");             guanli();             break;         case 2:             if(head == NULL)             {                 read_data();             }             system("cls");             youke();             break;         default:;         }         system("cls");     }while(k != 0);     return 0; }  void new_mv() {     int k = 0;     mv * add, * prev;     prev = head; //*****************修改***************     do     {          add = (mv *)malloc(sizeof(mv));          printf("请输入影片:\n");         scanf("%s",add->name);         printf("价格:\n");         scanf("%d",&add->money);         printf("票数:\n");         scanf("%d",&add->ticket);          if(head == NULL)         {             head = add;         }         else         {             prev->next = add;         }         add->next = NULL;         prev = add;           k = judge();     }while(k == 1); } void save_mv() {     FILE *fp;     mv * temp;     temp = head;       if((fp=fopen("mv.txt","wb"))==NULL)     {         printf("open file error!\n");         getchar();         exit(0);     }      do     {         fwrite(temp,sizeof(mv),1,fp);         printf("%d\n",temp);//测试使用，输出地址         temp = temp->next;     }     while(temp);      head = NULL;//////////////////////     fclose(fp); }  int judge() {     char c;     int a=1;     do     {         getchar();         printf("continue?<y\\n>");         scanf("%c",&c);         if(c=='y')         {             a=1;             break;//跳出判断函数。继续执行外层循环。         }         else         if(c=='n')         {             a=0;             break;//使外层do while 循环终止         }         else         {             a=1;//继续循环判断函数；         }     }while(a==1);     return a; }  void read_data() {     FILE * fp;     mv * temp;     mv * prev;      prev = head; //****************修改******prev要有指向的节点****************      if((fp=fopen("mv.txt","r"))==NULL)     {         printf("open file error!\n");         getchar();         exit(0);     }     while(!feof(fp))     {         temp = (mv *)malloc(sizeof(mv));         if(head == NULL)         {             head = temp;         }         else         {             prev->next = temp;         }         fread(temp,sizeof(mv),1,fp);         temp->next = NULL;         prev = temp;     }  }  void show()//展示 {     mv *temp;     temp = head;     while(temp->next)     {         printf("name:%s,noney:%d\n",temp->name,temp->money);         temp=temp->next;     } }  void menu_print() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.管理员登录\t\t\t\t|\n");     printf("|\t\t\t\t2.用户登录\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void guanli_menu() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.新建电影信息\t\t\t\t|\n");     printf("|\t\t\t\t2.增加电影信息\t\t\t\t|\n");     printf("|\t\t\t\t3.删除电影信息\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void guanli() {     int k = 1;     int switch_count=0;     do     {         guanli_menu();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)         {             {             case 0:                 k = 0;                 break;             case 1:                 new_mv();                 save_mv();                 break;             case 2:                 add_mv();                 break;             default:;             }         }     }while(k != 0); }  void youke_menu() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.查询当前电影\t\t\t\t|\n");     printf("|\t\t\t\t2.购票\t\t\t\t\t|\n");     printf("|\t\t\t\t3.退票\t\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void youke() {     int k = 1;     int switch_count = 0;     do     {         youke_menu();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)         {             {             case 0:                 k = 0;                 break;             case 1:                 show();                 //head = NULL; //****************查询完不该把头指针丢掉啊，                                 //否则接下来买票就找不到头指针从而导致错误                 break;             case 2:buy_mv();                 break;             default:leave_mv();             }         }     }while(k != 0); }  void buy_mv() {     int flag = 0;     char a[20] = {0};     mv *temp;     show();     temp = head;     printf("请输入你想买的电影的名字:");     scanf("%s",a);     while(temp)     {         if(strcmp(temp->name,a) == 0)         {             flag = 1;             printf("已经找到\n");             if(judge() == 0)             {                 break;             }             temp->ticket--;             printf("余票：%d",temp->ticket);             break;         }         else         {             temp = temp -> next;         }     }     if(flag == 0)     {         printf("没有找到你所找的电影：\n");     }      Sleep(1000);     system("cls"); }   void leave_mv() {     int flag=0;     char a[20];     mv *temp;     show();     temp=head;     printf("请输入你想退的票：");     scanf("%s",a);     while(temp)     {         if(strcmp(temp->name,a) == 0)         {             flag = 1;             printf("已经找到\n");             judge();             temp->ticket++;             printf("余票：%d",temp->ticket);             break;         }         else         {             temp = temp -> next;         }     }     if(flag == 0)     {         printf("没有找到你所找的电影：\n");     }      Sleep(2000);     system("cls"); }  void add_mv() {      int k = 0;     mv * add, * prev;      read_data();      prev = head;     do     {          add = (mv *)malloc(sizeof(mv));          printf("请输入影片:\n");         scanf("%s",add->name);         printf("价格:\n");         scanf("%d",&add->money);         printf("票数:\n");         scanf("%d",&add->ticket);           while(prev->next)         {             printf("name:%s,noney:%d\n",prev->name,prev->money);             prev = prev->next;         }         prev = add;         prev->next = NULL;          k = judge();     }while(k == 1);     save_mv();      //head = NULL; //************修改****给链表增加了一个节点不该把头节点    //                               空置啊******************** }                    修改的地方都在注释中，注意头节点呀，还有prev指针的指向，总感觉LZ指针乱指，以后多多注意一下！！！这种问题调试一下便出来了，还有让别人看代码，把注释写上呀，啥注释都没有。。。

user: user-1
content: 引用 9 楼 赵4老师的回复:不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 Editplus不就可以查看吗？查看16进制

user: user-2
content: 不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

user: user-2
content: 不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

user: user-1
content: ...... FILE *in; char ch;  ...... ch=fgetc(in);    //#1 while(!feof(in)) {     // 语句；     ch=fgetc(in); }   //当执行完语句#1后，指针已自动向后移一位，feof()判断的是后一位的情况。 //当吸走最后一个有效字符后，指针移到最后有效字符再往后一位，由前面分析已知，feof()判断结果为0，会再行//循环一次，正好处理完最后一个有效字符后循环结束。 可以先读取一个节点，然后文件指针不就自动后移了一下，然后把判断条件写到while里面。这也不就避免了多都一次的问题。 百度一下解决方法很多的，这只是一种！！！

user: user-0
content: 引用 5 楼 qianghaohao 的回复:没修改之前，查询电影票后再买票直接程序就奔溃了！！！多都一个节点是你那个while条件问题，建议看看fefo函数的详细用法！！！结贴吧，问题基本都说了！！！确实是feof函数不会用，在while（！feof（fp））循环里面放上fread函数以后，就算文件是空的也会循环一次。有没有什么办法能改掉这个结构。

user: user-1
content: 没修改之前，查询电影票后再买票直接程序就奔溃了！！！多都一个节点是你那个while条件问题，建议看看fefo函数的详细用法！！！结贴吧，问题基本都说了！！！

user: user-0
content: 引用 3 楼 cqh963852 的回复:[quote=引用 1 楼 qianghaohao 的回复:] #include<stdio.h> #include<stdlib.h> #include<string.h> #include<windows.h>  void new_mv(); void save_mv(); int judge(); void read_data();// void show();// void menu_print(); void guanli_menu(); void guanli(); void youke_menu(); void youke(); void buy_mv(); void leave_mv(); void add_mv();  typedef struct movie {     char name[20];     int money;     int ticket;     struct movie *next; }mv; mv * head = NULL;  int main() {     int k = 1;     int switch_count=0;     do     {         menu_print();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)//分支里面的函数用处理过后的函数，用 judge与其他函数组合出来的函数。         {         case 0:             k = 0;             break;         case 1:             system("cls");             guanli();             break;         case 2:             if(head == NULL)             {                 read_data();             }             system("cls");             youke();             break;         default:;         }         system("cls");     }while(k != 0);     return 0; }  void new_mv() {     int k = 0;     mv * add, * prev;     prev = head; //*****************修改***************     do     {          add = (mv *)malloc(sizeof(mv));          printf("请输入影片:\n");         scanf("%s",add->name);         printf("价格:\n");         scanf("%d",&add->money);         printf("票数:\n");         scanf("%d",&add->ticket);          if(head == NULL)         {             head = add;         }         else         {             prev->next = add;         }         add->next = NULL;         prev = add;           k = judge();     }while(k == 1); } void save_mv() {     FILE *fp;     mv * temp;     temp = head;       if((fp=fopen("mv.txt","wb"))==NULL)     {         printf("open file error!\n");         getchar();         exit(0);     }      do     {         fwrite(temp,sizeof(mv),1,fp);         printf("%d\n",temp);//测试使用，输出地址         temp = temp->next;     }     while(temp);      head = NULL;//////////////////////     fclose(fp); }  int judge() {     char c;     int a=1;     do     {         getchar();         printf("continue?<y\\n>");         scanf("%c",&c);         if(c=='y')         {             a=1;             break;//跳出判断函数。继续执行外层循环。         }         else         if(c=='n')         {             a=0;             break;//使外层do while 循环终止         }         else         {             a=1;//继续循环判断函数；         }     }while(a==1);     return a; }  void read_data() {     FILE * fp;     mv * temp;     mv * prev;      prev = head; //****************修改******prev要有指向的节点****************      if((fp=fopen("mv.txt","r"))==NULL)     {         printf("open file error!\n");         getchar();         exit(0);     }     while(!feof(fp))     {         temp = (mv *)malloc(sizeof(mv));         if(head == NULL)         {             head = temp;         }         else         {             prev->next = temp;         }         fread(temp,sizeof(mv),1,fp);         temp->next = NULL;         prev = temp;     }  }  void show()//展示 {     mv *temp;     temp = head;     while(temp->next)     {         printf("name:%s,noney:%d\n",temp->name,temp->money);         temp=temp->next;     } }  void menu_print() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.管理员登录\t\t\t\t|\n");     printf("|\t\t\t\t2.用户登录\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void guanli_menu() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.新建电影信息\t\t\t\t|\n");     printf("|\t\t\t\t2.增加电影信息\t\t\t\t|\n");     printf("|\t\t\t\t3.删除电影信息\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void guanli() {     int k = 1;     int switch_count=0;     do     {         guanli_menu();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)         {             {             case 0:                 k = 0;                 break;             case 1:                 new_mv();                 save_mv();                 break;             case 2:                 add_mv();                 break;             default:;             }         }     }while(k != 0); }  void youke_menu() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.查询当前电影\t\t\t\t|\n");     printf("|\t\t\t\t2.购票\t\t\t\t\t|\n");     printf("|\t\t\t\t3.退票\t\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void youke() {     int k = 1;     int switch_count = 0;     do     {         youke_menu();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)         {             {             case 0:                 k = 0;                 break;             case 1:                 show();                 //head = NULL; //****************查询完不该把头指针丢掉啊，                                 //否则接下来买票就找不到头指针从而导致错误                 break;             case 2:buy_mv();                 break;             default:leave_mv();             }         }     }while(k != 0); }  void buy_mv() {     int flag = 0;     char a[20] = {0};     mv *temp;     show();     temp = head;     printf("请输入你想买的电影的名字:");     scanf("%s",a);     while(temp)     {         if(strcmp(temp->name,a) == 0)         {             flag = 1;             printf("已经找到\n");             if(judge() == 0)             {                 break;             }             temp->ticket--;             printf("余票：%d",temp->ticket);             break;         }         else         {             temp = temp -> next;         }     }     if(flag == 0)     {         printf("没有找到你所找的电影：\n");     }      Sleep(1000);     system("cls"); }   void leave_mv() {     int flag=0;     char a[20];     mv *temp;     show();     temp=head;     printf("请输入你想退的票：");     scanf("%s",a);     while(temp)     {         if(strcmp(temp->name,a) == 0)         {             flag = 1;             printf("已经找到\n");             judge();             temp->ticket++;             printf("余票：%d",temp->ticket);             break;         }         else         {             temp = temp -> next;         }     }     if(flag == 0)     {         printf("没有找到你所找的电影：\n");     }      Sleep(2000);     system("cls"); }  void add_mv() {      int k = 0;     mv * add, * prev;      read_data();      prev = head;     do     {          add = (mv *)malloc(sizeof(mv));          printf("请输入影片:\n");         scanf("%s",add->name);         printf("价格:\n");         scanf("%d",&add->money);         printf("票数:\n");         scanf("%d",&add->ticket);           while(prev->next)         {             printf("name:%s,noney:%d\n",prev->name,prev->money);             prev = prev->next;         }         prev = add;         prev->next = NULL;          k = judge();     }while(k == 1);     save_mv();      //head = NULL; //************修改****给链表增加了一个节点不该把头节点    //                               空置啊******************** }                    修改的地方都在注释中，注意头节点呀，还有prev指针的指向，总感觉LZ指针乱指，以后多多注意一下！！！这种问题调试一下便出来了，还有让别人看代码，把注释写上呀，啥注释都没有。。。真心不是这个意思。问题出在read_data();函数上面，总是会多读一个节点。头结点是故意滞空的。应该是之前程序思路问题，以前没有做比较长的代码。链表也是第一次用，还麻烦再帮解决下。[/quote]头节点指向确实需要修改。。。但是现在函数都有问题。所以想先修改read_data();函数，至少能让函数正常了。。。

user: user-0
content: 引用 1 楼 qianghaohao 的回复:#include<stdio.h> #include<stdlib.h> #include<string.h> #include<windows.h>  void new_mv(); void save_mv(); int judge(); void read_data();// void show();// void menu_print(); void guanli_menu(); void guanli(); void youke_menu(); void youke(); void buy_mv(); void leave_mv(); void add_mv();  typedef struct movie {     char name[20];     int money;     int ticket;     struct movie *next; }mv; mv * head = NULL;  int main() {     int k = 1;     int switch_count=0;     do     {         menu_print();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)//分支里面的函数用处理过后的函数，用 judge与其他函数组合出来的函数。         {         case 0:             k = 0;             break;         case 1:             system("cls");             guanli();             break;         case 2:             if(head == NULL)             {                 read_data();             }             system("cls");             youke();             break;         default:;         }         system("cls");     }while(k != 0);     return 0; }  void new_mv() {     int k = 0;     mv * add, * prev;     prev = head; //*****************修改***************     do     {          add = (mv *)malloc(sizeof(mv));          printf("请输入影片:\n");         scanf("%s",add->name);         printf("价格:\n");         scanf("%d",&add->money);         printf("票数:\n");         scanf("%d",&add->ticket);          if(head == NULL)         {             head = add;         }         else         {             prev->next = add;         }         add->next = NULL;         prev = add;           k = judge();     }while(k == 1); } void save_mv() {     FILE *fp;     mv * temp;     temp = head;       if((fp=fopen("mv.txt","wb"))==NULL)     {         printf("open file error!\n");         getchar();         exit(0);     }      do     {         fwrite(temp,sizeof(mv),1,fp);         printf("%d\n",temp);//测试使用，输出地址         temp = temp->next;     }     while(temp);      head = NULL;//////////////////////     fclose(fp); }  int judge() {     char c;     int a=1;     do     {         getchar();         printf("continue?<y\\n>");         scanf("%c",&c);         if(c=='y')         {             a=1;             break;//跳出判断函数。继续执行外层循环。         }         else         if(c=='n')         {             a=0;             break;//使外层do while 循环终止         }         else         {             a=1;//继续循环判断函数；         }     }while(a==1);     return a; }  void read_data() {     FILE * fp;     mv * temp;     mv * prev;      prev = head; //****************修改******prev要有指向的节点****************      if((fp=fopen("mv.txt","r"))==NULL)     {         printf("open file error!\n");         getchar();         exit(0);     }     while(!feof(fp))     {         temp = (mv *)malloc(sizeof(mv));         if(head == NULL)         {             head = temp;         }         else         {             prev->next = temp;         }         fread(temp,sizeof(mv),1,fp);         temp->next = NULL;         prev = temp;     }  }  void show()//展示 {     mv *temp;     temp = head;     while(temp->next)     {         printf("name:%s,noney:%d\n",temp->name,temp->money);         temp=temp->next;     } }  void menu_print() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.管理员登录\t\t\t\t|\n");     printf("|\t\t\t\t2.用户登录\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void guanli_menu() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.新建电影信息\t\t\t\t|\n");     printf("|\t\t\t\t2.增加电影信息\t\t\t\t|\n");     printf("|\t\t\t\t3.删除电影信息\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void guanli() {     int k = 1;     int switch_count=0;     do     {         guanli_menu();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)         {             {             case 0:                 k = 0;                 break;             case 1:                 new_mv();                 save_mv();                 break;             case 2:                 add_mv();                 break;             default:;             }         }     }while(k != 0); }  void youke_menu() {     printf("*************************欢迎来到逗逼电影俱乐部**************************\n");     printf("|\t\t\t\t请输入选项\t\t\t\t|\n");     printf("|\t\t\t\t0.退出\t\t\t\t\t|\n");     printf("|\t\t\t\t1.查询当前电影\t\t\t\t|\n");     printf("|\t\t\t\t2.购票\t\t\t\t\t|\n");     printf("|\t\t\t\t3.退票\t\t\t\t\t|\n");     printf("*************************************************************************\n"); }  void youke() {     int k = 1;     int switch_count = 0;     do     {         youke_menu();         printf("\t\t\t请选择<0-3>:");         scanf("%d",&switch_count);         switch(switch_count)         {             {             case 0:                 k = 0;                 break;             case 1:                 show();                 //head = NULL; //****************查询完不该把头指针丢掉啊，                                 //否则接下来买票就找不到头指针从而导致错误                 break;             case 2:buy_mv();                 break;             default:leave_mv();             }         }     }while(k != 0); }  void buy_mv() {     int flag = 0;     char a[20] = {0};     mv *temp;     show();     temp = head;     printf("请输入你想买的电影的名字:");     scanf("%s",a);     while(temp)     {         if(strcmp(temp->name,a) == 0)         {             flag = 1;             printf("已经找到\n");             if(judge() == 0)             {                 break;             }             temp->ticket--;             printf("余票：%d",temp->ticket);             break;         }         else         {             temp = temp -> next;         }     }     if(flag == 0)     {         printf("没有找到你所找的电影：\n");     }      Sleep(1000);     system("cls"); }   void leave_mv() {     int flag=0;     char a[20];     mv *temp;     show();     temp=head;     printf("请输入你想退的票：");     scanf("%s",a);     while(temp)     {         if(strcmp(temp->name,a) == 0)         {             flag = 1;             printf("已经找到\n");             judge();             temp->ticket++;             printf("余票：%d",temp->ticket);             break;         }         else         {             temp = temp -> next;         }     }     if(flag == 0)     {         printf("没有找到你所找的电影：\n");     }      Sleep(2000);     system("cls"); }  void add_mv() {      int k = 0;     mv * add, * prev;      read_data();      prev = head;     do     {          add = (mv *)malloc(sizeof(mv));          printf("请输入影片:\n");         scanf("%s",add->name);         printf("价格:\n");         scanf("%d",&add->money);         printf("票数:\n");         scanf("%d",&add->ticket);           while(prev->next)         {             printf("name:%s,noney:%d\n",prev->name,prev->money);             prev = prev->next;         }         prev = add;         prev->next = NULL;          k = judge();     }while(k == 1);     save_mv();      //head = NULL; //************修改****给链表增加了一个节点不该把头节点    //                               空置啊******************** }                    修改的地方都在注释中，注意头节点呀，还有prev指针的指向，总感觉LZ指针乱指，以后多多注意一下！！！这种问题调试一下便出来了，还有让别人看代码，把注释写上呀，啥注释都没有。。。真心不是这个意思。问题出在read_data();函数上面，总是会多读一个节点。头结点是故意滞空的。应该是之前程序思路问题，以前没有做比较长的代码。链表也是第一次用，还麻烦再帮解决下。