2011-09-29 16 views
10

PerlでSTDINバッファをクリアする方法はありますか?私のプログラムの一部は長時間の出力(誰かが少数の文字を入力するのに十分な時間)を持っており、その出力の後に入力を求めますが、出力中に文字が入力された場合、入力に入力されたもの部。ここに私の問題の例があります:Perl STDINバッファをフラッシュする

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

出力には、そのforループの出力中に入力された文字が含まれます。どのようにしてSTDINを無効にするか、STDINバッファをフラッシュするか(またはそれを呼び出す前に余分な文字をSTDINに挿入しないようにする方法)?あなたはTerm::ReadKeyモジュールでこれを達成することができますように見えます

+0

[OK]を、私はすべての時間(今3日間この質問への答えのためではありません探していますしかし、私は少なくとも3〜4時間/日と言います)、まだ答えを見つけていませんでした。実際に私はPerlを知っている人と知っている同僚に尋ねました。彼らはどちらも知らないので、私は信じています私が入れていることを暗示している以上に努力しました。それ以外にも、私が求めていることをどうやってやるのか考えていますか?私はすでに3日ほど前にあなたのリンクを見ていたので、この問題を論理的に修正する方法でこれらの機能を実装しようとしましたが、うまく機能しませんでした。 – mcwillig

+1

'IO :: Handle; STDIN-> autoflush(1);' –

+0

あなたの答えをありがとう、しかし、これは問題を解決していない、また、私はautoflushを読むことを覚えているとフラッシュ出力だけのために良いですSTDERRとSTDOUTは入力されません。あなたが提案したものを試してみましたが、私はまだforループの出力中に入力した文字にSTDINで入力したものを加えました。 – mcwillig

答えて

13

#!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リセットSTDINSTDINから読み取ることができます。ユーザーがキーボードを押さなかったかのようにします。

キーボードでsleep(10)の間にこのコードを実行してから、プロンプトの後に他のテキストを入力すると、プロンプトが表示された後に入力したテキストのみが表示されます。

厳密に言えば、ReadMode 2は必要ありませんが、ユーザーがキーボードを叩いたときに画面が乱雑になることはありません。

これは一時的に
-4
{ local $/; <STDIN> } 

- ブロックの範囲に限定されるものでは - ちょうど一度にラインを読んだのではなく、すべてを読み取るためのperlに指示され、undefをする$ /、入力レコードの区切り文字を設定します。その後、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

- これは処理中にリターンがある場合にのみ機能します。そうでない場合は、誰かが入力するまで一時停止します –

関連する問題