[debug备忘录] 文件用while(!feof(fp))作为结束判定依据时,会多循环一次

文件用while(!feof(fp))作为结束判定依据时,会多循环一次

 

日期:2018-04-23

项目:学生管理系统

问题:文件用while(!feof(fp))作为结束判定依据时,会多循环一次

原因:feof(FILE *fp)只有在越过文件尾部尝试读取才能返回非零值(TRUE)。

现象:在检测输入的工号是否已经被创建的审核过程中,审核的循环比预期多一轮。

     //虽然此bug对该程序几乎没有影响,但修复bug的过程中能加深对C语言中feof、fgetc等函数与二进制流文件的读写理解。

     

bug代码:bug代码具体在15行

 1 void add_user_single()
 2 {
 3     char id[100] = {};
 4     puts("[单个添加]");
 5     if(lv == 1)
 6     {
 7         char path_user[30]= "../Users/Tch/tch.dat";
 8         printf("请输入添加教师的工号(3位):");
 9         do
10         {
11             scanf("%s",id);
12         }while(strlen(id)!=3);
13         
14         FILE* frwp = fopen(path_user,"rb+");
15         while(!feof(frwp))
16         {
17             fread(&tch,sizeof(tch),1,frwp);
18             puts("---------------------------------------------审核");
19             printf("ftell=%d sizeof(tch)=%d \n",ftell(frwp),sizeof(tch));
20             printf("id=%s tch.id_work=%s strcmp(id,tch.id_work)=%d \n",id,tch.id_work,strcmp(id,tch.id_work));
21             if(!strcmp(id,tch.id_work))
22             {
23                 printf("教师用户[%s]已存在,已将其复职!\n",id);
24                 sleep(2);
25             
26                 strcpy(tch.state,"1");
27                 fseek(frwp,-sizeof(tch),SEEK_CUR);
28                 fwrite(&tch,sizeof(tch),1,frwp);
29                 fclose(frwp);
30                 frwp = NULL;
31                 return;
32             }
33         }
34         fseek(frwp,0,SEEK_END);
35         strcpy(tch.id_work,id);
36         strcpy(tch.pwd,"000000");
37         strcpy(tch.state,"1");
38         fwrite(&tch,sizeof(tch),1,frwp);
39         puts("---------------------------------------------写入");
40         printf("ftell=%d sizeof(tch)=%d \n",ftell(frwp),sizeof(tch));
41         fclose(frwp);
42         frwp = NULL;
43     
44         num_tch++; 
45         printf("教师用户[%s]创建成功,按任意键退出!\n",id);
46         stdin->_IO_read_ptr = stdin->_IO_read_end;//清除缓存区,为getch()做准备
47         getch();    
48         sleep(1);
49     }
50 }
View Code

修复代码:将bug代码替换即可

1             int c;            
2             while((c=fgetc(frwp))==EOF)
3             {
4                 fseek(frwp,-1,SEEK_CUR);//注意fgetc()函数会移动位置指针    
View Code

bug原因:自身对feof(FILE *fp)函数理解不深。

解决bug花费时间:1小时

总结:1、feof(FILE *fp)只有在越过文件尾部尝试读取才能返回非零值(TRUE)。

   2、文件中先移动指针、后执行操作。

   3、文件指针好比是指哪一本书,位置指针(偏移量)就是一本书的页码。

   4、使用while((ch=fgetc(fp))!=EOF)方式读写二进制文件时要注意fgetc()会移动位置指针、ch最好用int类型而不能为char类型,避免fgetc()中途拿到FF

posted @ 2018-04-23 22:18  caoliu  阅读(2508)  评论(0编辑  收藏  举报