user-0 提问: 文件读写，怎样将文件数据读到链表？求助帮忙修改读取函数（read)，不胜感谢

回复:
user: user-0
content: 引用 9 楼 自信男孩的回复:int main() {     STUDENT *head = NULL;     head = read(head);     //head = init();       int nam,secret;        /*登录操作使用的变量*/     printf("\n\n\n\n");     printf("\t------------------------学生学学籍管理系统------------------------\n");     printf("\n\n");     printf("\t\t\t\t账号：");     scanf("%d", &nam);     printf("\n");     printf("\t\t\t\t密码：");     scanf("%d", &secret);     //system("cls");      if(nam == 172021 && secret==172021)     {         printf("\n\n");         printf("\t\t\t\t登录成功!!!\n\n");          for(;;)         {             switch(menu_select())             {                 case 1:                     head = create(head);//注册                     break;                  case 2:                     search(head);//查询                     break;                  case 3:                     revise(head);//修改                     break;                 case 4:                     head=del(head);//删除                     break;                 case 5:                     printstu(head);//显示信息                     break;                 case 6:                     exit(0);//退出系统                     break;                 default:                     printf("输入错误");                     break;              }         }     }     else     {         printf("输入错误，请重新登录");     }    }  main  STUDENT *create(STUDENT *head)//创建链表，注册学生信息 {     char answer;     STUDENT *p, *pcur;     STUDENT *last = NULL;      pcur = last = head;     //system("cls");     do     {         p = (STUDENT *)malloc(sizeof(STUDENT));         if (!p)             exit(0);         printf("\n\n");         printf("----------学生信息录入---------- \n");         printf("\n");         printf("------请输入：\n");         printf("\t学号：");         scanf("%s", p->num);         printf("\t姓名：");         scanf("%s", p->name);         printf("\t性别：");         scanf("%s", p->sex);         printf("\t年龄：");         scanf("%d", &p->age);         printf("\t户籍：");         scanf("%s", p->addr);         printf("\t专业：");         scanf("%s", p->major);         printf("\t系别：");         scanf("%s", p->xb);         printf("\n");         printf("\t是否继续录入?(Y or N):   ");         getchar();   /* for '\n' */         scanf("%c", &answer);          while (pcur) {             if (pcur->num == p->num) {                 free(p);                 continue;             }             last = pcur;             pcur = pcur->next;         }           if(last) {             last->next = p;             last = last->next;         } else {             last = p;             head = last;         }     } while(answer=='Y'||answer=='y');      last->next = NULL;      save(head);    /* store infor into file */     printf("\n");     printf("\t保存成功！！！\n\n");     return head; }   create STUDENT *read(STUDENT *head)//读取文件函数（读文件） {     int ret;     FILE *fp;     STUDENT *p, *prev;      p = head;     if ((fp = fopen("student.txt","r"))==NULL)     {         printf("failed to open the file!!");         exit(1);     }      while (1)     {         p = (STUDENT *)malloc(sizeof(STUDENT));         if (!p)             exit(0);         ret = fscanf(fp,"%s %s %s %d %s %s %s", p->num, p->name,p->sex, &p->age,p->addr,p->major,p->xb);         if (ret < 7)             break;         if (!head) {             head = p;             prev = head;         } else {             prev->next = p;             prev = p;         }     }     free(p);     prev->next = NULL;      fclose(fp);      return head; } 修改的部分建议对比一下，作为一个参考吧 太谢谢你啦，我再仔细想想

user: user-1
content: 引用 5 楼 Hhq128 的回复:[quote=引用 4 楼 Hhq128的回复:][quote=引用 2 楼 自信男孩的回复:]很纳闷，create函数里已经创建了链表（在内存里），为啥save之后还要read呢？并且read函数里传入的head已经是已经有文件的数据（因为刚把内存里的数据写入文件--save函数操作的）。 重新运行是head会初始化为NULL，read函数只是读取第一次save存储的student.txt文件，在第二次运行时直接用printfstu输出[/quote] 现在就是不知道怎样将第一次存储的txt文件读出来显示[/quote] read功能，建议你每次程序启动后先从文件里去读取，第一次去读时，文件为空。第二次启动后就有新数据了。 不能刚save就去read，这相当于把苹果从手里放入袋子里，然后马上又从袋子里拿出来。

user: user-1
content: int main() {     STUDENT *head = NULL;     head = read(head);     //head = init();       int nam,secret;        /*登录操作使用的变量*/     printf("\n\n\n\n");     printf("\t------------------------学生学学籍管理系统------------------------\n");     printf("\n\n");     printf("\t\t\t\t账号：");     scanf("%d", &nam);     printf("\n");     printf("\t\t\t\t密码：");     scanf("%d", &secret);     //system("cls");      if(nam == 172021 && secret==172021)     {         printf("\n\n");         printf("\t\t\t\t登录成功!!!\n\n");          for(;;)         {             switch(menu_select())             {                 case 1:                     head = create(head);//注册                     break;                  case 2:                     search(head);//查询                     break;                  case 3:                     revise(head);//修改                     break;                 case 4:                     head=del(head);//删除                     break;                 case 5:                     printstu(head);//显示信息                     break;                 case 6:                     exit(0);//退出系统                     break;                 default:                     printf("输入错误");                     break;              }         }     }     else     {         printf("输入错误，请重新登录");     }    }  main  STUDENT *create(STUDENT *head)//创建链表，注册学生信息 {     char answer;     STUDENT *p, *pcur;     STUDENT *last = NULL;      pcur = last = head;     //system("cls");     do     {         p = (STUDENT *)malloc(sizeof(STUDENT));         if (!p)             exit(0);         printf("\n\n");         printf("----------学生信息录入---------- \n");         printf("\n");         printf("------请输入：\n");         printf("\t学号：");         scanf("%s", p->num);         printf("\t姓名：");         scanf("%s", p->name);         printf("\t性别：");         scanf("%s", p->sex);         printf("\t年龄：");         scanf("%d", &p->age);         printf("\t户籍：");         scanf("%s", p->addr);         printf("\t专业：");         scanf("%s", p->major);         printf("\t系别：");         scanf("%s", p->xb);         printf("\n");         printf("\t是否继续录入?(Y or N):   ");         getchar();   /* for '\n' */         scanf("%c", &answer);          while (pcur) {             if (pcur->num == p->num) {                 free(p);                 continue;             }             last = pcur;             pcur = pcur->next;         }           if(last) {             last->next = p;             last = last->next;         } else {             last = p;             head = last;         }     } while(answer=='Y'||answer=='y');      last->next = NULL;      save(head);    /* store infor into file */     printf("\n");     printf("\t保存成功！！！\n\n");     return head; }   create STUDENT *read(STUDENT *head)//读取文件函数（读文件） {     int ret;     FILE *fp;     STUDENT *p, *prev;      p = head;     if ((fp = fopen("student.txt","r"))==NULL)     {         printf("failed to open the file!!");         exit(1);     }      while (1)     {         p = (STUDENT *)malloc(sizeof(STUDENT));         if (!p)             exit(0);         ret = fscanf(fp,"%s %s %s %d %s %s %s", p->num, p->name,p->sex, &p->age,p->addr,p->major,p->xb);         if (ret < 7)             break;         if (!head) {             head = p;             prev = head;         } else {             prev->next = p;             prev = p;         }     }     free(p);     prev->next = NULL;      fclose(fp);      return head; } 修改的部分建议对比一下，作为一个参考吧

user: user-0
content: 引用 6 楼 赵4老师的回复:不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8   能帮我修改下吗，就是要求要第二次重启时直接可以显示数据

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仍继续读;读写的内容当字节看待 弄混了  仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8

user: user-0
content: 引用 4 楼 Hhq128的回复:[quote=引用 2 楼 自信男孩的回复:]很纳闷，create函数里已经创建了链表（在内存里），为啥save之后还要read呢？并且read函数里传入的head已经是已经有文件的数据（因为刚把内存里的数据写入文件--save函数操作的）。 重新运行是head会初始化为NULL，read函数只是读取第一次save存储的student.txt文件，在第二次运行时直接用printfstu输出[/quote] 现在就是不知道怎样将第一次存储的txt文件读出来显示

user: user-0
content: 引用 2 楼 自信男孩的回复:很纳闷，create函数里已经创建了链表（在内存里），为啥save之后还要read呢？并且read函数里传入的head已经是已经有文件的数据（因为刚把内存里的数据写入文件--save函数操作的）。 重新运行是head会初始化为NULL，read函数只是读取第一次save存储的student.txt文件，在第二次运行时直接用printfstu输出

user: user-0
content: 百度里面的题目设定不一样啊，，

user: user-1
content: 很纳闷，create函数里已经创建了链表（在内存里），为啥save之后还要read呢？并且read函数里传入的head已经是已经有文件的数据（因为刚把内存里的数据写入文件--save函数操作的）。

user: user-2
content: 百度搜相关关键字。

user: user-0
content: 引用 10 楼 Hhq128的回复:[quote=引用 9 楼 自信男孩的回复:]int main() {     STUDENT *head = NULL;     head = read(head);     //head = init();       int nam,secret;        /*登录操作使用的变量*/     printf("\n\n\n\n");     printf("\t------------------------学生学学籍管理系统------------------------\n");     printf("\n\n");     printf("\t\t\t\t账号：");     scanf("%d", &nam);     printf("\n");     printf("\t\t\t\t密码：");     scanf("%d", &secret);     //system("cls");      if(nam == 172021 && secret==172021)     {         printf("\n\n");         printf("\t\t\t\t登录成功!!!\n\n");          for(;;)         {             switch(menu_select())             {                 case 1:                     head = create(head);//注册                     break;                  case 2:                     search(head);//查询                     break;                  case 3:                     revise(head);//修改                     break;                 case 4:                     head=del(head);//删除                     break;                 case 5:                     printstu(head);//显示信息                     break;                 case 6:                     exit(0);//退出系统                     break;                 default:                     printf("输入错误");                     break;              }         }     }     else     {         printf("输入错误，请重新登录");     }    }  main  STUDENT *create(STUDENT *head)//创建链表，注册学生信息 {     char answer;     STUDENT *p, *pcur;     STUDENT *last = NULL;      pcur = last = head;     //system("cls");     do     {         p = (STUDENT *)malloc(sizeof(STUDENT));         if (!p)             exit(0);         printf("\n\n");         printf("----------学生信息录入---------- \n");         printf("\n");         printf("------请输入：\n");         printf("\t学号：");         scanf("%s", p->num);         printf("\t姓名：");         scanf("%s", p->name);         printf("\t性别：");         scanf("%s", p->sex);         printf("\t年龄：");         scanf("%d", &p->age);         printf("\t户籍：");         scanf("%s", p->addr);         printf("\t专业：");         scanf("%s", p->major);         printf("\t系别：");         scanf("%s", p->xb);         printf("\n");         printf("\t是否继续录入?(Y or N):   ");         getchar();   /* for '\n' */         scanf("%c", &answer);          while (pcur) {             if (pcur->num == p->num) {                 free(p);                 continue;             }             last = pcur;             pcur = pcur->next;         }           if(last) {             last->next = p;             last = last->next;         } else {             last = p;             head = last;         }     } while(answer=='Y'||answer=='y');      last->next = NULL;      save(head);    /* store infor into file */     printf("\n");     printf("\t保存成功！！！\n\n");     return head; }   create STUDENT *read(STUDENT *head)//读取文件函数（读文件） {     int ret;     FILE *fp;     STUDENT *p, *prev;      p = head;     if ((fp = fopen("student.txt","r"))==NULL)     {         printf("failed to open the file!!");         exit(1);     }      while (1)     {         p = (STUDENT *)malloc(sizeof(STUDENT));         if (!p)             exit(0);         ret = fscanf(fp,"%s %s %s %d %s %s %s", p->num, p->name,p->sex, &p->age,p->addr,p->major,p->xb);         if (ret < 7)             break;         if (!head) {             head = p;             prev = head;         } else {             prev->next = p;             prev = p;         }     }     free(p);     prev->next = NULL;      fclose(fp);      return head; } 修改的部分建议对比一下，作为一个参考吧 太谢谢你啦，我再仔细想想[/quote] 以结帖，谢谢你啊！！我在需要读取文件的函数之前加了read函数，这样就不用改变原来的指针顺序了。可以运行，谢谢