[英]Why does fgetc move the file position indicator backwards?
當我在Windows(Visual Studio 15)上構建時,在freeBSD系統上運行良好的程序失敗。 它在這里陷入無盡的循環:
//...
while (1) {
if ('@' == fgetc(f)) {
// we do some stuff here. irrelevant for stackoverflow question
break;
}
fseek(f, -1, SEEK_CUR);
if (0 != fseek(f, -1, SEEK_CUR)) {
// Beginning of file.
break;
}
}
//...
仔細觀察(通過添加一堆fgetpos()調用),我發現fgetc 向后移動文件位置指示器。 因此,它會錯過文件的開頭,如果它們與末尾的位置不是3的倍數,則會丟失一些“ @”。
我注意到這僅在使用以下文件f打開時發生
fopen(filename, "a+");
//text mode read/append
當我將其更改為
fopen(filename, "ab+");
//binary mode read/append
然后一切都會按預期進行。 我認為對於我的代碼而言,始終使用二進制模式是安全的。 但是仍然存在兩個問題:
引用C11 7.21.9.2的fseek
函數:
對於文本流,offset應該為零,或者offset應該是對與同一文件相關聯的流上的ftell函數的較早成功調用返回的值,並且whence應該為SEEK_SET。
C標准不包括在文本模式下打開的流上使用SEEK_CUR
的whence參數調用fseek
。 以二進制模式打開文件似乎是一個更好的選擇。
fgetpos()
返回的值作為文件中的偏移量可能沒有意義,它僅應作為參數傳遞給fsetpos()
。
通常,您應該嘗試更改算法,以避免依賴於流中的向后搜索,尤其是依賴fseek()
錯誤似乎不可靠。 而是使用ftell()
或fgetpos()
將位置保存在fgetc()
之前,並在需要時使用fseek(pos, SEEK_SET, fp)
或fsetpos()
恢復該位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.