[問題] C - 含有fwrite的迴圈變成無限循環

看板C_and_CPP作者 (OHAI)時間10年前 (2015/06/23 17:30), 編輯推噓5(5023)
留言28則, 6人參與, 最新討論串1/2 (看更多)
開發平台(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++ 加上有段時間沒有碰程式語言了,可以說是沒啥底子,現在都靠網路資料自學 在不知如何除錯後,決定快速複習一下十誡與板規然後在這裡第一次發問 如果我犯了甚麼常見錯誤也請直接指出 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.230.118.61 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1435051834.A.E44.html

06/23 21:46, , 1F
fwrite之後加一行fflush
06/23 21:46, 1F

06/24 01:22, , 2F
感謝樓上,目前是加了一句fflush(NULL)
06/24 01:22, 2F

06/24 01:24, , 3F
看來要先去把檔案處理的函式都重新研究過一遍
06/24 01:24, 3F

06/24 10:29, , 4F
上網查了一下,還有種方法是取消緩衝區
06/24 10:29, 4F

06/24 12:33, , 5F
fflush(img);
06/24 12:33, 5F

06/24 16:37, , 6F
fflush(NULL)...這種寫法我還是第一次看到 OAO
06/24 16:37, 6F

06/24 17:05, , 7F
只有fflush(img)的話還是會掉進無窮迴圈
06/24 17:05, 7F

06/24 17:06, , 8F
試過了一定要在加句fflush(Stdout)才行
06/24 17:06, 8F

06/24 17:11, , 9F
傳給fflush空指標的話,會清空所有輸出緩衝區
06/24 17:11, 9F

06/24 22:01, , 10F
這真奇怪. 在 Linux 不用修改就正常執行了.
06/24 22:01, 10F

06/24 22:01, , 11F
但用 codeblocks-mingw 的情況下, 除了R大所說 fflush() 外,
06/24 22:01, 11F

06/24 22:02, , 12F
我在 fwrite() 後加個 fseek(img, 0, SEEK_CUR); 也可正常...
06/24 22:02, 12F

06/24 22:02, , 13F
似乎是 fwrite() 做完後, ftell() 會正確回報,
06/24 22:02, 13F

06/24 22:02, , 14F
但 fread() 的讀取點還在原處, 所以要用 ftell() 幫它移一下?
06/24 22:02, 14F

06/24 22:04, , 15F
訂正 fseek()
06/24 22:04, 15F

06/24 22:24, , 16F
感謝意見,但最近又沒空研究程式了
06/24 22:24, 16F

06/24 22:25, , 17F
加上我也想重寫程式看能不能更有效率
06/24 22:25, 17F

06/24 22:25, , 18F
可能之後會發新文來討論
06/24 22:25, 18F

06/28 10:13, , 19F
我查了一下cplusplus.com,fseek除了origin 設為SEEK_SET
06/28 10:13, 19F

06/28 10:14, , 20F
或offset為0之外,其他值都是non-portable
06/28 10:14, 20F

06/30 13:22, , 21F
即使將 fseek(img, -4, SEEK_CUR);
06/30 13:22, 21F

06/30 13:23, , 22F
改為 fseek(img, ftell(img)-4, SEEK_SET);
06/30 13:23, 22F

06/30 13:25, , 23F
原程式問題依然發生. 故此問題也許和 fseek() portable 無關?
06/30 13:25, 23F

07/01 03:05, , 24F
我也到cplusplus.com看了,文字模式才限定用SEEK_SET
07/01 03:05, 24F

07/01 03:07, , 25F
真正non-portable的只有SEEK_END
07/01 03:07, 25F

07/01 03:09, , 26F
在維基教科書C Programming/File IO有提到,
07/01 03:09, 26F

07/01 03:14, , 27F
輸出跟輸入是不能直接交互使用的 目前找到線索就這樣
07/01 03:14, 27F

07/01 03:16, , 28F
或許用malloc與free把整個檔案一次讀入記憶體處理較好
07/01 03:16, 28F
文章代碼(AID): #1LYISwv4 (C_and_CPP)
文章代碼(AID): #1LYISwv4 (C_and_CPP)