簡體   English   中英

為什么在空流上調用std :: istream :: ignore時不返回?

[英]Why does std::istream::ignore not return when called on an empty stream?

std :: cin是一個全局對象,因此,我始終希望在使用它之前將其設置為良好狀態。 但是,在未使用的cin上調用ignore()時,該函數不會返回。

請參見下面的示例代碼。 沒有用戶干預,執行不會到達第8行( cout )。 在我的測試中,此行為與是否有第二個參數(分隔符,我已經嘗試過'\\ n'和EOF)一致。

我已經看過一些在線參考資料,但是我不明白為什么會這樣。

#include <limits>
#include <iostream>
#include <string>
std::string readInput() {
    std::string input = "";
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    std::cout << "We never get here..." << std::endl;
    std::getline(std::cin, input);
    return input;
}
int main() {    
    std::string foo = readInput();  
}
  1. 為什么在這種情況下ignore()不返回?
  2. 如何使用安全地重置並清空std :: cin?

參見第二個參數'\\n' 您正在要求讀取不超過'\\n'字符並忽略它們。 由於流上沒有'\\n' ,因此這意味着阻塞直到接收到一個。

希望很明顯,僅應在知道流中存在'\\n'時才進行此調用。

因此,您的第二個問題的答案是,在使用之前, 請勿執行任何操作 ,因為流上始終沒有數據。

清除流的時間是從讀它的一些數據之后 ; 然后根據您使用的讀取操作,您將知道是否有換行符。

請注意,沒有這樣的操作“清除流中的內容”(這是有意設計)。 相反,您的操作將是“清除行的其余部分”之類的操作,其中“行”被定義為下一個換行符。 而輸入將來自使用行的文件或用戶按Enter的交互式終端。

文檔中所述:

ignore表現為UnformattedInputFunction。 在構造並檢查了哨兵對象之后,它將從流中提取字符並丟棄它們,直到出現以下任何一種情況:[...]輸入序列中的下一個可用字符c是delim,由Traits :: eq_int_type確定(特性:: to_int_type(c),delim)。 分隔符字符被提取並丟棄。 如果delim為Traits :: eof(),則此測試被禁用

因此,如果流為空,它將觸發對相應流緩沖區的underflow()的調用,因為在您的情況下,忽略正在等待'\\ n'。

注意:當要確保流緩沖區完全為空時,可以調用cin.rdbuf()-> in_avail()以獲取仍在等待從輸入緩沖區中提取的字符數,如果緩沖區為0,則為0是空的。 但是,這是高度依賴於實現的,因為它可以與現成的Visual Studio一起使用。 另一方面,對於GCC,必須先調用cin.sync_with_stdio(false)才能擁有內部緩沖。 但是,它不適用於這樣的LLVM。

暫無
暫無

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

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