標準輸入與Ctrl D/Ctrl Z

標準輸入設備是行緩衝的,當從鍵盤上輸入字符串,輸入的字符串會首先被送到輸入緩衝區中存儲,當銨下回車鍵後纔會去檢測輸入緩衝區中是否有了數據(也就是說fgets、fgetchar等函數這個時候纔去從緩衝區中讀數據)。我們可以把輸入緩衝區理解爲文件,那麼對於這個文件來說,它也有結束的時候,輸入函數在從緩衝區中讀文件的時候也會去檢測有沒有流結束標誌(EOF),這種標誌是通過Ctrl+d 或 Ctrl+z產生的。Ctrl+d和Ctrl+z的檢測主要分爲兩種:阻塞式 和 非阻塞式。

阻塞式: 指只有在按下回車鍵後纔對之前是否有按下Ctrl+z進行檢測。

非阻塞式: 指在按下Ctrl+d之後立即響應。

在非阻塞式模式下,按下Ctrl+d後立即響應,如果在此之前有輸入字符,則Ctrl+d就相當於回車,即把輸入的內容送到輸入緩衝區供讀取使用,此時Ctrl+d不作爲流結束符使用,下次按下的Ctrl+d則作爲流結束標誌。如果按下Ctrl+d之前沒有輸入任何數據,剛Ctrl+d作爲流結束標誌,表示標準輸入設備對應的文件結束。linux下輸入就是非阻塞式的。

在Windows系統中輸入一般採用阻塞式模式來對Ctrl+Z進行檢測,在這種模式下,只有按下回車對會去檢測之前有沒有按下Ctrl+z,纔會去檢測流是否結束。那麼就會有這樣一個問題,就是在按下回車之前,輸入緩衝區並不能檢測到是否有Ctrl+z按下,所以即使按了Ctrl+z,照樣還可以從鍵盤去輸入內空,但是Ctrl+z這賓輸入的內容到時候並不會被讀取到,因爲在緩衝區檢測時,如果檢測到Ctrl+z(結束標誌),就會認爲輸入流結束了,那麼後邊的內容就不會被讀進行,而被丟掉。

另外還有一點需要說明,就是Ctrl+z或Ctrl+d並不會產生一個普通的ASCII碼值,也就是說它不會產生一個字符,不會被放到輸入緩衝區中,所以大家也是讀不到它的,那麼可能有人會懷疑那我們時寫的類似於這樣的判斷是怎麼回事:

while(ch != EOF )

其實EOF就是一個複數(多數情況下就是-1),如果檢測到輸入流結束標誌,則會讓從鍵盤讀取的函數返回值-1,這樣就可以實現當文件結束時退出循環的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章