2011-09-29 14 views
10

¿Hay alguna manera de borrar el buffer STDIN en Perl? Una parte de mi programa tiene una salida larga (tiempo suficiente para que alguien ingrese algunos caracteres) y después de esa salida pido una entrada, pero si los caracteres fueron ingresados ​​durante la salida, se "agregan" a lo que se ingresa en la entrada parte. Aquí hay un ejemplo de mi problema:Flushing Perl STDIN buffer

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

La salida incluiría los caracteres ingresados ​​durante la salida de ese ciclo for. ¿Cómo podría desactivar STDIN o eliminar el búfer STDIN (o de otra forma no permitir que se inserten caracteres adicionales en STDIN antes de llamarlo)?

+0

Ok, me han estado buscando una respuesta a esta pregunta durante 3 días ahora (no cada hora de todos los días, pero yo diría al menos 3 o 4 horas por día) y aún no he encontrado una respuesta, de hecho, les pregunté a mis colegas, que también conocen y usan Perl, y tampoco lo saben, así que sí creo que he puesto más esfuerzo de lo que insinúas que he puesto, que aparte, ¿tienes alguna idea de cómo hacer lo que estoy pidiendo? Debido a que ya revisé su enlace, hace aproximadamente 3 días, intenté implementar esas funciones de una manera que lógicamente solucionaría este problema, y ​​no funcionó. – mcwillig

+1

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

+0

Gracias por su respuesta, pero esto no solucionó el problema, también, recuerdo que leer autoflush y flush solo son buenos para la salida, tales como STDERR y STDOUT, no entrada. Cuando probé lo que sugeriste, sigo recibiendo los caracteres que ingresé durante la salida del bucle for más lo que ingresé en STDIN. – mcwillig

Respuesta

13

Parece que se puede lograr esto con el módulo 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'"; 

Esto es lo que sucede:

  • ReadMode 2 significa "poner el modo de entrada en el modo normal, pero apagar el eco". Esto significa que cualquier golpeteo del teclado que haga el usuario mientras se encuentre en su código computacionalmente caro no se reflejará en la pantalla. Todavía se entró en búfer STDIN 's aunque, por lo ...
  • ReadMode 3 convierte STDIN en modo cbreak, lo que significa STDIN tipo de personal se van después de cada pulsación de tecla. Es por eso que ...
  • while(defined($key = ReadKey(-1))) {} sucede. Esto está eliminando los caracteres que el usuario ingresó durante el código de costo computacional. Luego ...
  • ReadMode 0 restablece STDIN, y puede leer en STDIN como si el usuario no hubiera golpeado el teclado.

Cuando ejecuto este código y explosión en el teclado durante la sleep(10), a continuación, introduzca un texto diferente después del indicador, sólo se imprime el texto que he escrito después de la pronta aparición.

Estrictamente hablando, el ReadMode 2 no es necesario, pero lo coloco allí para que la pantalla no se sature con el texto cuando el usuario golpea el teclado.

-4
{ local $/; <STDIN> } 

Esta forma temporal - se limita al alcance del bloque - establece $ /, el registro separador de entrada, para ser undef, que le dice a Perl acaba de leer todo lo que en vez de leer una línea a la vez. Luego lee todo lo que está disponible en STDIN y no hace nada con él, lo que hace que el búfer se vacíe.

Después de eso, puede leer STDIN de forma normal.

+2

Esto no funcionará. Los bloques de llamada '' hasta que se pueda leer un "registro". Pero si '$ /' es 'undef', no puede haber un final del registro, por lo que bloqueará hasta que se alcance EOF. – mob

0

que tenían el mismo problema y lo resolvió con sólo descartar nada en STDIN después del procesamiento de la siguiente manera:

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

- me acabo de dar cuenta de que esto solo funciona si hay un retorno durante el procesamiento; de lo contrario, se detendrá hasta que alguien acceda a ingresar –

Cuestiones relacionadas