[問題] 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