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

楼主: Rollnmeow (OHAI)   2015-06-23 17:30:28
开发平台(Platform): (Ex: VC++, GCC, Linux, ...)
Code::Blocks, GNU GCC, Windows 7
问题(Question):
这是一个以含有以fread回传值作while循环判断式的档案处里程式
但每次执行总会陷入无穷循环,同时档案不断增大
上网查了一下很有可能是fwrite会使档案增大因而无法读到eof
但我已经将fread写在while的条件式里头,
每次写入之前应该就会进行判断是否读到结尾
不知是否跟我使用的变量类型有关(unsigned long)?
程式码(Code):(请善用置底文网页, 记得排版)
#include <stdio.h>
#include <stdlib.h>
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;
while(fread(&buf, 4, 1, img)){
printf("%lXh\n", ftell(img));
//除错用,把档案指标位置输出在萤幕上
buf = ((buf << 4) & 0xF0F0F0F0) | ((buf >> 4) & 0xF0F0F0F);
//这段是主要的处理
fseek(img, -4, SEEK_CUR); //倒退回读入资料的位置
fwrite(&buf, 4, 1, img); //覆蓋原本资料
}
fclose(img);
return 0;
}
补充说明(Supplement):
个人非程式设计相关科系出身,在课堂上只学到了基础的C/C++
加上有段时间没有碰程式语言了,可以说是没啥底子,现在都靠网络资料自学
在不知如何除错后,决定快速复习一下十诫与板规然后在这里第一次发问
如果我犯了什么常见错误也请直接指出
作者: zetab   2015-06-23 21:46:00
fwrite之后加一行fflush
楼主: Rollnmeow (OHAI)   2015-06-24 01:22:00
感谢楼上,目前是加了一句fflush(NULL)看来要先去把档案处理的函式都重新研究过一遍
作者: EdisonX (卡卡兽)   2015-06-24 12:33:00
fflush(img);
作者: LPH66 (-6.2598534e+18f)   2015-06-24 16:37:00
fflush(NULL)...这种写法我还是第一次看到 OAO
楼主: Rollnmeow (OHAI)   2015-06-24 17:05:00
只有fflush(img)的话还是会掉进无穷循环试过了一定要在加句fflush(Stdout)才行传给fflush空指标的话,会清空所有输出缓冲区
作者: yvb   2015-06-24 22:01:00
这真奇怪. 在 Linux 不用修改就正常执行了.但用 codeblocks-mingw 的情况下, 除了R大所说 fflush() 外,我在 fwrite() 后加个 fseek(img, 0, SEEK_CUR); 也可正常...似乎是 fwrite() 做完后, ftell() 会正确回报,但 fread() 的读取点还在原处, 所以要用 ftell() 帮它移一下?订正 fseek()
楼主: Rollnmeow (OHAI)   2015-06-24 22:24:00
感谢意见,但最近又没空研究程式了加上我也想重写程式看能不能更有效率可能之后会发新文来讨论
作者: kaneson (Lance)   2015-06-28 10:13:00
我查了一下cplusplus.com,fseek除了origin 设为SEEK_SET或offset为0之外,其他值都是non-portable
作者: yvb   2015-06-30 13:22:00
即使将 fseek(img, -4, SEEK_CUR);改为 fseek(img, ftell(img)-4, SEEK_SET);原程式问题依然发生. 故此问题也许和 fseek() portable 无关?
楼主: Rollnmeow (OHAI)   2015-07-01 03:05:00
我也到cplusplus.com看了,文字模式才限定用SEEK_SET真正non-portable的只有SEEK_END在维基教科书C Programming/File IO有提到,输出跟输入是不能直接交互使用的 目前找到线索就这样或许用malloc与free把整个档案一次读入内存处理较好

Links booklink

Contact Us: admin [ a t ] ucptt.com