[英]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.