簡體   English   中英

為什么std :: cin的提取器操作符等待用戶輸入?

[英]Why does std::cin's extractor operator wait for user input?

我知道這可能是一個愚蠢的問題,但我不確定如何從終端獲得用戶輸入實際上是有效的。

我從概念上理解輸入/輸出,我使用它們沒有問題,但是當涉及到如何在基本級別實際實現它們時,我迷失了方向。

據我所知,所有流對象都使用一種緩沖區。 如果你提取所有到達eof的字符。 這部分我可能錯了,我想了解更多。 例如,當我們使用std :: cin的提取器運算符時,它會等待輸入。 它如何區分等待輸入和達到eof(沒有別的東西可讀)?

std::cin沒有做任何特別的事情。 像所有的文件輸入,它發出讀取系統級( read Unix中, ReadFile在Windows中),足夠字節填充它的緩存(通常是一些超過1K今天)。 它是檢測輸入來自鍵盤的系統,行為不同:從文件中,系統將讀取盡可能多的字節,直到文件末尾或請求的數字,並立即返回。 從鍵盤,系統通常會將字符讀入內部緩沖區,直到進入,允許編輯(后退空間等),並且只有在輸入時才會將此緩沖區傳遞回調用者(在添加新行標記之后) )。

編輯:

作為討論中提到的元素的摘要排序:我將以Unix系統中的情況為例(但Windows基本相同,以報告不同信息的方式為模)。 istream本身是緩沖的。 當您嘗試提取字符( >>運算符, istream::get等)時,流將從其緩沖區返回它。 如果緩沖區中沒有剩余字符,它將向系統發出read請求,其地址和緩沖區大小。 (在今天的系統中,我會驚訝地看到一個小於1K的緩沖區。)系統用它做什么將取決於文件描述符指定的內容:

一份文件
系統將從文件中的當前位置復制字節,直到它填滿緩沖區或到達文件末尾。 它返回它復制的字節數(如果有錯誤,則返回-1)。
鍵盤
對於鍵盤,系統維護自己的內部緩沖區,並逐行讀取。 當用戶按下回車鍵時,此緩沖區僅被視為“就緒”; 在此之前,系統將不會從`read`返回。 這允許系統實現行編輯; 例如處理退格之類的東西。 當您按Enter鍵時,系統會將(系統特定的)新行序列添加到緩沖區,並返回其已復制到緩沖區中的字符數。 (因此,不是0,因為有新行。)此過程可以通過兩種方式進行修改:Unix和Windows都有一個特殊字符(Unix下的control-D,Windows下的control-Z),它告訴系統返回立即從讀取,當前緩沖區包含的內容。 如果你在一行的開頭,緩沖區什么都沒有,`read`返回0個字符讀取,並且流將它視為文件的結尾。 如果流緩沖區大小小於行中的字符數(因為你在沒有新行的情況下平靜地鍵入了100000個字符),`read`將返回適合緩沖區的最大值,並且下一個` read`將立即返回該行的其余部分(或者下一個n`read`將立即返回,直到讀取整行)。
管道
系統將等待,直到管道中請求的字符數量盡可能多,或者管道打開以進行寫入時不再有剩余的進程。 然后它將復制請求的字符數(或更少,寫入側關閉),並返回復制的數字。

如果read指示錯誤,則流將設置badbit ; 如果read返回0個字符讀取,則流將其視為文件末尾。

std :: istream可能具有有限數量的數據(硬盤驅動器上的文件,......)或無限量的數據(傳感器,......,交互式用戶輸入)。 此外,可能還有一個代表EOF的特殊字符。

來自控制台/終端的交互式輸入是無限輸入。 除非輸入特殊字符(Linux:ctl-d),否則流永遠不會達到EOF。

來自管道的非交互式輸入將(應該/可能)以EOF結尾。

暫無
暫無

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

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