Re: [问题] C - 含有fwrite的循环变成无限循环

楼主: Rollnmeow (OHAI)   2015-07-02 16:09:05
为了除错,将程式码修改了一下
int main()
{
FILE *img = fopen("image.bmp", "r+b");
if (img == NULL) {
perror("");
return 1;
}
fseek(img, 10, SEEK_SET);
long off = 0;
fread(&off, 4, 1, img);
fseek(img, off, SEEK_SET);
unsigned long buf = 0;
int fread_rv = 0;
while(1){
fread_rv = fread(&buf, 4, 1, img);
printf("fread returned value:%d\n", fread_rv);
if (fread_rv == 0) break;
printf("after reading:%lXh\n", ftell(img));
buf = ((buf << 4) & 0xF0F0F0F0) | ((buf >> 4) & 0xF0F0F0F);
fseek(img, -4, SEEK_CUR);
printf("before writing:%lXh\n", ftell(img));
fwrite(&buf, 4, 1, img);
printf("after writing:%lXh\n\n", ftell(img));
fseek(img, 0, SEEK_CUR);
}
fclose(img);
return 0;
}
这次拿掉while的条件式,多一个fread_rv去接fread的回传值
改用if来判断循环是否重复执行
执行结果正常,但如果把最后一行fseek去掉则又会陷入无穷循环了
,因为fread总是会回传1
我当下就判断一定是我在档案读写的使用上有了解不清的部分
于是我又到cplusplus查了一遍fseek,发现有句
"On streams open for update (read+write),
a call to fseek allows to switch between reading and writing."
接下来又找到维基教科书里面有写在r+b或r+模式下一个output不能马上接一个input
,除非之间有使用fflush/fseek/fsetpos/rewind,反过来也是类似
之后我用debugger去观察执行最后一行fseek(img, 0, SEEK_CUR)的效果
发现每次执行完这行,档案就被修改了一次
所以fseek也是会清空缓冲区并输出,这应该也是cplusplus那句话的由来
维基教科书提到这部份的连结:
https://en.wikibooks.org/wiki/C_Programming/File_IO#Opening_Files

Links booklink

Contact Us: admin [ a t ] ucptt.com