2011-09-29 14 views
10

C'è un modo per cancellare il buffer STDIN in Perl? Una parte del mio programma ha una lunga uscita (tempo sufficiente per qualcuno per inserire alcuni caratteri) e dopo quell'output chiedo l'input, ma se i caratteri sono stati inseriti durante l'output, vengono "attaccati" a qualsiasi cosa venga immessa nell'input parte. Ecco un esempio del mio problema:Flushing Perl buffer STDIN

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

L'output includerebbe qualsiasi carattere immesso durante l'output da quel ciclo for. Come potrei disabilitare STDIN o svuotare il buffer STDIN (o in un altro modo per non consentire l'inserimento di caratteri extra in STDIN prima di chiamarlo)?

+0

Ok, ho cercato una risposta a questa domanda per 3 giorni la società (non ogni ora di ogni giorno, ma direi almeno 3 o 4 ore al giorno) e non ho ancora trovato una risposta, infatti ho chiesto ai miei colleghi, che conoscono e usano anche il Perl, e non lo sanno neanche io, quindi credo che ho fatto più sforzi di quanto tu stia insinuando che ho inserito, a parte questo, hai qualche idea su come fare quello che sto chiedendo? Poiché ho già controllato il tuo link, circa 3 giorni fa, ho provato a implementare tali funzioni in un modo che avrebbe risolto il problema logicamente e non ha funzionato. – mcwillig

+1

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

+0

Grazie per la risposta, ma questo non ha risolto il problema, inoltre, ricordo che leggere autoflush e flush sono buoni solo per l'output, ad esempio come STDERR e STDOUT, non input. Quando ho provato ciò che mi hai suggerito, ricevo comunque i caratteri che ho inserito durante l'output del ciclo for più ciò che ho inserito in STDIN. – mcwillig

risposta

13

Sembra che si può raggiungere questo obiettivo con il modulo 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'"; 

Ecco cosa succede:

  • ReadMode 2 significa "mettere la modalità di ingresso in modalità normale, ma spegnere echo". Ciò significa che qualsiasi battito della tastiera che l'utente fa mentre sei nel tuo codice computazionalmente costoso non verrà visualizzato sullo schermo. Viene comunque immesso nel buffer STDIN, quindi ...
  • ReadMode 3 trasforma STDIN in modalità cbreak, ovvero STDIN si arrossisce dopo ogni pressione di un tasto. Ecco perché ...
  • while(defined($key = ReadKey(-1))) {} accade. Questo è lo svuotamento dei caratteri che l'utente ha inserito durante il codice computazionalmente costoso. Quindi ...
  • ReadMode 0 ripristina STDIN e puoi leggere da STDIN come se l'utente non avesse battuto sulla tastiera.

Quando ho eseguito questo codice e botto sulla tastiera durante la sleep(10), quindi inserire qualche altro testo dopo il prompt, viene stampato solo il testo ho digitato dopo è apparso il prompt.

Strettamente parlando, lo ReadMode 2 non è necessario, ma l'ho messo lì in modo che lo schermo non diventi ingombrante di testo quando l'utente batte sulla tastiera.

-4
{ local $/; <STDIN> } 

Questa temporanea - limita il campo di applicazione del blocco - imposta $ /, all'ingresso record separatore, per essere undef, che dice a perl di leggere proprio tutto invece di leggere una riga alla volta. Quindi legge tutto disponibile su STDIN e non fa nulla con esso, quindi svuota il buffer.

Dopodiché, è possibile leggere STDIN normalmente.

+2

Questo non funzionerà. I blocchi di chiamata '' finché un "record" non può essere letto. Ma se '$ /' è 'undef', non ci può essere la fine del record, quindi bloccherà fino al raggiungimento di EOF. – mob

0

Ho avuto lo stesso problema e risolto da solo scartando qualsiasi cosa in STDIN dopo l'elaborazione in questo modo:

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

- appena realizzato funziona solo se c'è un ritorno durante l'elaborazione, altrimenti si interromperà fino a quando qualcuno non entra –

Problemi correlati