《C陷阱与缺陷》:更新顺序文件

来源:互联网 发布:mac网游 编辑:程序博客网 时间:2024/04/28 13:53

许多系统中的标准输入/输出库都允许程序打开一个文件,同时进行写入和读出的操作:

FILE * fp;  fp = fopen(file, "r+"); 

上面的例子代码打开了文件名由变量 file 指定的文件,对于存取权限的设定表明程序希望对这个文件进行输入和输出操作。

编程者也许认为,程序一旦执行上述操作完毕,就可以自由地交错进行读出和写入操作。遗憾的是,事实总是难随人愿,为了保持与过去不能同时进行读写操作的程序的向下兼容性,一个输入操作不能随后直接紧跟着一个输出操作,反之亦然。如果要同时进行输入和输出操作,必须在其中插入 fseek 函数的调用

下面的程序片段似乎更新了一个顺序文件中选定的记录:

FILE * fp;  struct record rec;  //... ...  while (fread((char *)&rec, sizeof(rec), 1, fp) == 1) {      /* 对rec执行某些操作 */      if (/* rec 必须被重新写入 */)     {           fseek(fp, -(long)sizeof(rec), 1);           fwrite((char *)&rec, sizeof(rec), 1, fp);      }  }  

这段代码乍看上去没有问题。但是实际上出错的方式令人难以察觉。如果一个记录需要被重新写入,也就是是说,fwrite 函数得到执行,对这个文件执行的下一个操作将是循环开始的 fread 函数。因为在 fwrite 函数调用与 fread 函数调用之间缺少一个 fseek 函数的调用,所以无法进行上述操作。解决办法如下:

FILE * fp;  struct record rec;  //... ...  while (fread((char *)&rec, sizeof(rec), 1, fp) == 1){      /* 对rec执行某些操作 */      if (/* rec 必须被重新写入 */)     {           fseek(fp, -(long)sizeof(rec), 1);           fwrite((char *)&rec, sizeof(rec), 1, fp);           fseek(fp, 0L, 1);  //新增 fseek    }  }  

第二个 fseek 函数虽然看上去什么也没有做,但它改变了文件的状态,使得文件现在可以正常地读取了。

本文摘自:《C陷阱与缺陷》

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕期吐的胃疼怎么办 买的巧克力化了怎么办 跑步后脸上出盐怎么办 头发被剪的很短怎么办 孩子做事情拖拉不专注怎么办 新热水壶有味道怎么办 新买电热壶有味怎么办 两个月狗耳朵臭怎么办 狗狗牙齿变黄怎么办 人用了狗沐浴露怎么办 狗狗吞食牙膏吐怎么办? 狗狗吞食了牙膏怎么办 大猪拉稀不吃食怎么办 猪不发烧不吃食怎么办 天天吃自热米饭怎么办 喝了加热包水怎么办啊 蛋挞没有盒子装怎么办 塑料饭盒盖子被吸住了怎么办 火腿淹的有臭味怎么办 微波炉热饭盖子打不开怎么办 夏天带饭容易馊怎么办? 保温饭盒里有气打不开怎么办 保温饭盒摔了一下打不开怎么办 饭盒跟盖子盖一起打不开怎么办 玻璃杯子盖被水吸住打不开怎么办 电饭煲热剩饭没加水怎么办 微波炉碗盖子吸住了怎么办 微波炉转饭盖子吸住了怎么办 玻璃碗放进微波炉打不开怎么办 乐扣微波炉加热后打不开怎么办 美的微波炉盖子打不开怎么办 美的微波炉门都打不开了怎么办 饭煮好了有异味怎么办 一正常吃饭就胖怎么办 高铁盒饭没15的怎么办 上火车前票丢了怎么办 减肥期吃了汉堡怎么办 寿司店鳗鱼有刺怎么办 吃泡面胃难受该怎么办 吃上火的东西脸上长痘痘怎么办 减肥期间吃撑了怎么办