簡體   English   中英

使用 std::istream::peek() 總是安全的嗎?

[英]Is it always safe to use std::istream::peek()?

我通常教我的學生處理文件輸入的安全方法是:

while (true) {
    // Try to read
    if (/* failure check */) {
        break;
    }
    // Use what you read
}

這使我和許多人免於經典和大部分時間錯誤:

while (!is.eof()) {
    // Try to read
    // Use what you read
}

但是人們真的很喜歡這種形式的循環,因此在學生代碼中看到這種形式變得很常見:

while (is.peek()!=EOF) { // <-- I know this is not C++ style, but this is how it is usually written
    // Try to read
    // Use what you read
}

現在的問題是:這段代碼有問題嗎? 是否存在某些情況無法完全按預期工作的極端情況? 好的,這是兩個問題。

編輯其他詳細信息:在考試期間,您有時會向學生保證文件的格式正確,因此他們無需進行所有檢查,只需驗證是否有更多數據。 大多數時候我們處理二進制格式,這讓你完全不用擔心空格(因為數據都是有意義的)。

雖然接受的答案是完全清楚和正確的,但我仍然希望有人嘗試評論peek()unget()的聯合行為。

我想到了unget()東西,因為我曾經觀察到(我相信它是在 Windows 上)通過查看 4096 內部緩沖區限制(如此有效地導致加載新緩沖區),取消獲取前一個字節(最后一個前一個緩沖區)失敗。 但我可能是錯的。 所以這是我的另一個疑問:我錯過了一些已知的東西,它可能在標准或某些庫實現中得到了很好的編碼。

is.peek()!=EOF告訴您輸入流中是否還有字符,但它不會告訴您下一次讀取是否會成功:

while (is.peek()!=EOF) {
    int a;
    is >> a;
    // Still need to test `is` to verify that the read succeeded
}

is >> a可能由於多種原因而失敗,例如輸入實際上可能不是數字。

所以如果你可以這樣做,這沒有意義

int a;
while (is >> a) { // reads until failure of any kind
    // use `a`
}

或者,也許更好:

for (int a; is >> a;) { // reads until failure of any kind
    // use `a`
}

或者您的第一個示例,在這種情況下, is.peek()!=EOF將變得多余。

這是假設您希望循環在每次失敗時退出,遵循您的第一個代碼示例,而不僅僅是在文件結束時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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