假設我們有這段代碼:
while ((ch = getc(fp)) != EOF) {
...
}
這就是我假設回圈會起作用的方式,請告訴我它是否正確/是否犯了任何錯誤:
getc從 I/O 流中讀取字符fpgetc將其存盤在變數中chch經過測驗EOF,通常相當于-1(取決于它是如何為您定義的)。- 回傳時
EOF表示End Of File已設定特定流的指示符。這意味著先前的讀取操作已嘗試讀取檔案末尾。
我有一個重要的問題:
在這個回圈中,當getc到達檔案末尾時,它是否會嘗試最終讀取檔案末尾,從而導致它最終回傳EOF?
uj5u.com熱心網友回復:
getc從 I/O 流中讀取字符fp
更準確地說,getc 嘗試從fp流中讀取字符。
getc將其存盤在變數中ch
getc回傳一個值,如果該值在型別中可表示,則int賦值ch = getc(fp)將該值存盤在中。如果它不可表示,則以取決于型別的方式進行轉換。為了避免這種轉換的復雜性,應該是.chchchchint
ch針對EOF……進行了測驗
是的,結果值與ch進行比較EOF。這使得型別很重要:如果getc回傳EOFandch是一個不能表示 的值的字符型別EOF,那么轉換將導致不同的值存盤在 中ch,然后它不會比較等于EOF。
…通常相當于
-1(取決于它是如何為您定義的)。
EOF在許多 C 實作中可能為 -1,但它具有任何負值是正常的int。
- 回傳時
EOF表示End Of File已設定特定流的指示符。
不,EOF回傳表明已到達檔案末尾(并嘗試進一步讀取)或發生錯誤。C 2018 7.21.7.5 3 說:
該
getc函式從 指向的輸入流中回傳下一個字符stream。如果流處于檔案末尾,則設定流的檔案結束指示符,并且 getc 回傳EOF。如果發生讀取錯誤,則設定流的錯誤指示符并getc回傳EOF。
這意味著先前的讀取操作已嘗試讀取檔案末尾。
這意味著先前的操作或當前操作試圖讀取檔案末尾或先前的操作或當前操作遇到錯誤(并且這些先前的條件尚未清除,如呼叫rewindor clearerr)。
在這個回圈中,當
getc到達檔案末尾時,它是否會嘗試最終讀取檔案末尾,從而導致它最終回傳EOF?
如果流連接到一個有限且不變大小的檔案,則該回圈最終將嘗試讀取檔案末尾,如果回圈主體中沒有任何內容重置檔案位置,此時EOF將回傳并且回圈將出口。但是,如果流連接到一些“無限”的資料供應,例如管道,則回圈可能永遠不會遇到流的結尾。
uj5u.com熱心網友回復:
一旦檔案流到達 EOF,狀態應該是粘性的——檔案流上的所有輸入操作在每次呼叫時都會簡單地報告 EOF。您可以呼叫clearerr()以重置錯誤/EOF 狀態,在這種情況下,輸入函式將嘗試讀取更多資料,直到再次遇到 EOF。
如果輸入設備是終端,則有一段時間 GNU C 庫不會使狀態保持粘性。如今,情況已不再如此。
uj5u.com熱心網友回復:
不,它從不嘗試讀取檔案末尾,因為ch != EOF當您到達末尾并且回圈停止時條件失敗。這發生在上一次迭代讀取檔案的最后一個字符時,所以你在最后,而不是過去。
如果您確實繼續嘗試閱讀,EOF除非您呼叫clearerr(). 這在處理擴展的檔案時很有用(想想tail -f命令是如何作業的——它會一直讀取到 EOF,然后繼續檢查檔案是否已經增長)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/505057.html
上一篇:如何用C撰寫可移植的二進制檔案?
