看板 C_and_CPP 關於我們 聯絡資訊
開發平台(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
zetab: fwrite之後加一行fflush 06/23 21:46
Rollnmeow: 感謝樓上,目前是加了一句fflush(NULL) 06/24 01:22
Rollnmeow: 看來要先去把檔案處理的函式都重新研究過一遍 06/24 01:24
Rollnmeow: 上網查了一下,還有種方法是取消緩衝區 06/24 10:29
EdisonX: fflush(img); 06/24 12:33
LPH66: fflush(NULL)...這種寫法我還是第一次看到 OAO 06/24 16:37
Rollnmeow: 只有fflush(img)的話還是會掉進無窮迴圈 06/24 17:05
Rollnmeow: 試過了一定要在加句fflush(Stdout)才行 06/24 17:06
Rollnmeow: 傳給fflush空指標的話,會清空所有輸出緩衝區 06/24 17:11
yvb: 這真奇怪. 在 Linux 不用修改就正常執行了. 06/24 22:01
yvb: 但用 codeblocks-mingw 的情況下, 除了R大所說 fflush() 外, 06/24 22:01
yvb: 我在 fwrite() 後加個 fseek(img, 0, SEEK_CUR); 也可正常... 06/24 22:02
yvb: 似乎是 fwrite() 做完後, ftell() 會正確回報, 06/24 22:02
yvb: 但 fread() 的讀取點還在原處, 所以要用 ftell() 幫它移一下? 06/24 22:02
yvb: 訂正 fseek() 06/24 22:04
Rollnmeow: 感謝意見,但最近又沒空研究程式了 06/24 22:24
Rollnmeow: 加上我也想重寫程式看能不能更有效率 06/24 22:25
Rollnmeow: 可能之後會發新文來討論 06/24 22:25
kaneson: 我查了一下cplusplus.com,fseek除了origin 設為SEEK_SET 06/28 10:13
kaneson: 或offset為0之外,其他值都是non-portable 06/28 10:14
yvb: 即使將 fseek(img, -4, SEEK_CUR); 06/30 13:22
yvb: 改為 fseek(img, ftell(img)-4, SEEK_SET); 06/30 13:23
yvb: 原程式問題依然發生. 故此問題也許和 fseek() portable 無關? 06/30 13:25
Rollnmeow: 我也到cplusplus.com看了,文字模式才限定用SEEK_SET 07/01 03:05
Rollnmeow: 真正non-portable的只有SEEK_END 07/01 03:07
Rollnmeow: 在維基教科書C Programming/File IO有提到, 07/01 03:09
Rollnmeow: 輸出跟輸入是不能直接交互使用的 目前找到線索就這樣 07/01 03:14
Rollnmeow: 或許用malloc與free把整個檔案一次讀入記憶體處理較好 07/01 03:16