2011-09-29 59 views
10

有什麼方法可以清除Perl中的STDIN緩衝區?我的程序的一部分有很長的輸出(有足夠的時間讓某人輸入幾個字符),然後在輸出之後要求輸入,但是如果在輸出過程中輸入了字符,它們就會被「粘貼」到任何在輸入處輸入的內容部分。這裏是我的問題的一個例子:Flushing Perl STDIN緩衝區

for(my $n = 0; $n < 70000; $n++){ 
    print $n . "\n"; 
} 
chomp(my $input = <STDIN>); 
print $input . "\n"; 

輸出將包括在該for循環的輸出期間輸入的任何字符。我怎麼能禁用STDIN或刷新STDIN緩衝區(或者在調用它之前不允許額外的字符被插入到STDIN中)?

+0

好吧,我一直在尋找的答案,這個問題的3天,現在每隔一小時(不,但我會說至少每天3或4小時)並且還沒有找到答案,實際上我問了我的同事,他們也知道並使用Perl,他們也不知道,所以我確實相信我已經投入了比你更多的努力,暗示我已經投入了,除此之外,你對於如何去做我所要求的有什麼想法嗎?因爲我大約3天前已經瀏覽了你的鏈接,試圖以一種能夠在邏輯上解決這個問題的方式來實現這些功能,並且它不起作用。 – mcwillig

+1

'使用IO :: Handle; STDIN-> autoflush(1);' – 2011-09-29 20:48:32

+0

謝謝你的回答,但是,這並沒有解決問題,另外,我記得閱讀autoflush和刷新只適用於輸出,例如作爲STDERR和STDOUT,而不是輸入。當我嘗試了你所建議的內容時,我仍然可以看到我在輸入for循環期間輸入的字符以及我在STDIN中輸入的內容。 – mcwillig

回答

13

它看起來像您可以用Term::ReadKey模塊實現這一點:

#!perl 

use strict; 
use warnings; 
use 5.010; 

use Term::ReadKey; 

say "I'm starting to sleep..."; 
ReadMode 2; 
sleep(10); 
ReadMode 3; 
my $key; 
while(defined($key = ReadKey(-1))) {} 
ReadMode 0; 
say "Enter something:"; 
chomp(my $input = <STDIN>); 
say "You entered '$input'"; 

這裏發生了什麼:

  • ReadMode 2意味着「輸入模式爲普通模式,但回聲關閉」。這意味着用戶在使用昂貴的計算代碼時所做的任何鍵盤操作都不會回顯到屏幕上。它仍然進入STDIN的緩衝區,所以...
  • ReadMode 3STDIN轉爲cbreak模式,意爲STDIN種類在每次按鍵後都會被刷新。這就是爲什麼...
  • while(defined($key = ReadKey(-1))) {}發生。這將清除用戶在計算繁瑣代碼期間輸入的字符。然後...
  • ReadMode 0重置STDIN,您可以從STDIN讀取,就好像用戶沒有敲擊鍵盤一樣。

當我sleep(10)中運行這段代碼和Bang在鍵盤上,然後進入後提示某些其他文本,只打印出我輸入的提示出現後的文本。

嚴格來說,ReadMode 2不是必需的,但是我把它放在那裏,所以當用戶敲擊鍵盤時,屏幕不會與文本混雜在一起。

-4
{ local $/; <STDIN> } 

這將暫時 - 限於塊的範圍 - 設置$ /,輸入記錄分隔符,是民主基金,它告訴Perl,只是看什麼,而不是每次讀一行。然後讀取STDIN上可用的所有內容,並不對其執行任何操作,從而刷新緩衝區。

之後,您可以像平常一樣閱讀STDIN。

+2

這不起作用。 ''呼叫阻塞,直到可以讀取「記錄」。但是如果'$ /'是'undef',則記錄可能沒有結束,所以它會阻塞,直到到達EOF。 – mob

0

我有同樣的問題,並通過這樣的處理後只是放棄任何東西STDIN解決它:

for(my $n = 0; $n < 70000; $n++){ 
    print $n . "\n"; 
} 
my $foo=<STDIN>; 
print "would you like to continue [y/n]: "; 
chomp(my $input = <STDIN>); 
print $input . "\n"; 
+0

- 剛剛意識到這隻適用於處理過程中有回報,否則它會暫停,直到有人點擊輸入 –