2011-12-14 24 views
5

I tener este programa que toma una matriz de palabras y le pregunta al usuario escribir una frase que tiene cada una de la palabra de la matriz:Vuelva a ejecutar un bucle de iteración

@words = qw(Hi world thanks); 
foreach $word (@words) 
{ 
     print "Enter a line with word:$word\n"; 
     chomp($input = <STDIN>); 
     if($input=~/$word/i) 
     { 
       print "Great\n"; 
     } else { 
       print "Incorrect. Type a line containing $word\n"; 
     } 
} 

Si el usuario escribe una entrada con la palabra, funciona bien. Pero si no lo hace, solo imprime el mensaje de error y pasa a la siguiente palabra. Lo quiero, indica al usuario que vuelva a ingresar las entradas para la misma palabra. Pero cómo ? Probé a continuación, no funcionó.

Respuesta

18

Puede usar un redo en este caso para reiniciar la iteración actual.

foreach my $word (@words) 
{ 
     print "Enter a line with word:$word\n"; 
     chomp($input = <STDIN>); 
     if($input=~/$word/i) 
     { 
       print "Great\n"; 
     } else { 
       print "Incorrect. Type a line contaning $word\n"; 
       redo; # restart current iteration. 
     } 
} 

Una alternativa menos recomendable es usar un goto:

foreach my $word (@words) 
{ 
     INPUT:print "Enter a line with word:$word\n"; 
     chomp($input = <STDIN>); 
     if($input=~/$word/i) 
     { 
       print "Great\n"; 
     } else { 
       print "Incorrect. Type a line contaning $word\n"; 
       goto INPUT; 
     } 
} 
+1

Gracias. Funciona. Perl era tantas maneras de hacer las cosas. –

+0

Yo votaría por 'rehacer'. –

+2

Holy cow, 14 upvotes for 'redo'? Mucho tiempo desde que he visto una aclamación tan aplastante en la etiqueta perl. – TLP

3

me gustaría crear un bucle infinito while para salir de:

#!/usr/bin/env perl 

use strict; 
use warnings; 

my @words = qw(Hi world thanks); 
foreach my $word (@words) { 
    print "Enter a line with word: $word\n"; 
    while (1) { 
    chomp(my $input = <STDIN>); 
    if($input=~/$word/i) { 
     print "Great\n"; 
     last; 
    } else { 
     print "Incorrect. Type a line contaning $word\n"; 
    } 
    } 
} 

por supuesto que lo haría probablemente por separado la lógica de cada palabra individual en un sub, luego recorra eso:

#!/usr/bin/env perl 

use strict; 
use warnings; 

my @words = qw(Hi world thanks); 
get_word($_) for @words; 

sub get_word { 
    my $word = shift or die "Need a word"; 
    print "Enter a line with word: $word\n"; 
    while (1) { 
    chomp(my $input = <STDIN>); 
    if($input=~/$word/i) { 
     print "Great\n"; 
     last; 
    } else { 
     print "Incorrect. Type a line contaning $word\n"; 
    } 
    } 
} 
3

Mientras que redo es definitivamente más lindo, aquí hay una versión con while ... continue. Se basa en un bucle interno que solo sale cuando se ingresa la palabra correcta e imprime una corrección para cada respuesta incorrecta.

use strict; 
use warnings; 

my @words = qw(Hi world thanks); 
foreach my $word (@words) { 
    print "Enter a line with word: $word\n"; 
    while (my $input = <>) { 
     last if $input =~ /$word/; 
    } continue { 
     print "Incorrect. Type a line contaning $word\n"; 
    } 
    print "Great\n"; 
} 

Tenga en cuenta que chomp no es necesario en este caso.

+0

Supongo que 'chomp' realmente no se necesita en ninguno de estos, sino solo porque la expresión regular no está anclada, y no es una comparación' eq'. –

+0

@JoelBerger Por lo tanto, "en este caso". – TLP

+0

oh, pensé que querías decir en tu caso. Gotcha –

Cuestiones relacionadas