簡體   English   中英

為什么fgetc向后移動文件位置指示器?

[英]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.2fseek函數:

對於文本流,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM