Besserer "Abfrage"-Code
Pot
- perl
0 Skrilax0 _King Lully0 Pot0 _King Lully0 Pot
0 迪拉斯0 Pot
Moin,
Ein paar Leute und ich schreiben gerade an einem Bash-Script. Das ganze will ich jetzt auf perlisch umschreiben. Manchmal kommen da so Fragen mit ja/nein Antworten und einer Standartantwort (bsp: nein):
[code=bash]
while [ true ]; do
echo -n "Frage [j/N] ";
read antwort
case $antwort in
n|N|"")
do_something
break;;
j|J)
do_something
break;;
*)
echo "Ungültige Angabe!"
;;
esac
done
[/code]
Mir ist klar, dass eine Endlosschleife nicht gescheit ist, die nachher mit break abgebrochen wird. Auch wegen diesem Grund frage ich hier nach.
Nun: wie schreibe ich das korrekt in Perl? case gibts ja net also kommt nur eine if in Frage. Die Endlosschleife will ich auch rausnehmen.
Gibts da irgend eine optimale Lösung dafür?
Mit freundlichen Gruessen,
Pot
Hallo!
Keine Vorgefertigte Lösung, aber ein Denkansatz, wie man das ganze besser Algorithmieren könnte.
Packe die Schleife doch nur um die Eingabe selbst, und formuliere die korrekte Eingabe als Abbruchsbedingung dafür. Und erst wenn eine korrekte Eingabe sichergestellt ist, wertest du diese nach der Schleife aus.
Grüße, Skrilax
Moin,
Keine Vorgefertigte Lösung, aber ein Denkansatz, wie man das ganze besser Algorithmieren könnte.
Mehr habe ich auch nicht erwartet ;-)
Packe die Schleife doch nur um die Eingabe selbst, und formuliere die korrekte Eingabe als Abbruchsbedingung dafür. Und erst wenn eine korrekte Eingabe sichergestellt ist, wertest du diese nach der Schleife aus.
Also wieder eine Endlosschleife? Da ich Perl in der shebang mit dem Argument -w aufrufe, meckert das liebe Perl wegen der Endlosschleife ^^
Aber danke für deine Idee.. die hat mich auf soetwas gebracht:
print("Frage\n");
$antwort="undef";
until($antwort eq "j" || $antwort eq "J" || $antwort eq "n" || $antwort eq "N")
{
$antwort = <STDIN>;
chop $antwort;
}
do_something();
War das in deinem Sinne?
Noch eine Frage nebenbei: Ist es Möglich, mit if auch case-insensitive zu testen? Dann entfällt dieses lästige Prüfen auf j,J,n,N
Danke,
Pot
Hallo!
War das in deinem Sinne?
Genau :-)
Eine Endlosschleife liegt doch aber nur dann vor, wenn du als Bedingung einen immer wahren Ausdruck formulierst. Das ist jetzt ja nicht mehr der Fall, also sollte es auch nicht mehr als Endlosschleife erkannt werden.
Noch eine Frage nebenbei: Ist es Möglich, mit if auch case-insensitive zu testen? Dann entfällt dieses lästige Prüfen auf j,J,n,N
Das nicht, aber du kannst die Zeichenkette zuerst umwandeln und dann vergleichen:
until ( (lc $antwort eq 'j') || (lc $antwort eq 'n') )
oder eben mit RegExp, mit wirklicher "case-insensitivity":
until ($antwort =~ /^(?:j|n)$/i)
kleine Sache nebenbei, du meinst doch sicherlich sowas:
$antwort = undef;
also ohne die Stringbegrenzer ("). Außerdem empfehle ich dir die Verwendung von 'use strict;', dann müsste es
my $antwort; # Initialisierung ist dann auch nicht notwendig
heißen.
Grüße, Skrilax
Eine Endlosschleife liegt doch aber nur dann vor, wenn du als Bedingung einen immer wahren Ausdruck formulierst. Das ist jetzt ja nicht mehr der Fall, also sollte es auch nicht mehr als Endlosschleife erkannt werden.
Jop. Ist mir klar.
Das nicht, aber du kannst die Zeichenkette zuerst umwandeln und dann vergleichen:
until ( (lc $antwort eq 'j') || (lc $antwort eq 'n') )
oder eben mit RegExp, mit wirklicher "case-insensitivity":
until ($antwort =~ /^(?:j|n)$/i)
Achja na klar das lc gibts noch^^ Danke.
kleine Sache nebenbei, du meinst doch sicherlich sowas:
$antwort = undef;
also ohne die Stringbegrenzer ("). Außerdem empfehle ich dir die Verwendung von 'use strict;', dann müsste es
my $antwort; # Initialisierung ist dann auch nicht notwendig
heißen.
Danke für die Hinweise! Bin halt noch unerfahren in perl ^^
Grüße, Skrilax
Pot
Hallo Pot,
$antwort="undef";
until($antwort eq "j" || $antwort eq "J" || $antwort eq "n" || $antwort eq "N")
{
$antwort = <STDIN>;
chop $antwort;
}
do_something();
Für Schleifen, die in jedem Fall mindestens ein Mal durchlaufen werden müssen, nimmt man eher eine do...while/until-Schleife.
Außerdem würde ich bei einer falschen Eingabe eine Fehlermeldung ausgeben.
Viele Grüße aus Freiburg,
Marian
Die Zahl der Fragen dürfte endlich sein, auch darum emfehlen wir hier das gute alte for(;;)-Konstrukt.
Allerdings dürfte das do_something() frageabhängig sein. Insofern ist eine Serie von if-Blöcken eine Idee.
Oder ein objektorientierter Ansatz natürlich. ;)
Moin,
Die Zahl der Fragen dürfte endlich sein, auch darum emfehlen wir hier das gute alte for(;;)-Konstrukt.
Natürlich ist sie endlich. Eigentlich ist es ja nur eine Frage. Sie wird einfach solange wiederholt, bis eine korrekte Antwort angegeben wurde.
Danke für die Antwort.
Die Zahl der Fragen dürfte endlich sein, auch darum emfehlen wir hier das gute alte for(;;)-Konstrukt.
Natürlich ist sie endlich. Eigentlich ist es ja nur eine Frage. Sie wird einfach solange wiederholt, bis eine korrekte Antwort angegeben wurde.
Dann ist while genau richtig. Denn while ist für Anweisungssequenzen bei denen vorab nicht klar ist, wie oft der Code ausgeführt werden soll bzw. wann die Abbruchbedingung erfüllt ist.
Moin,
Die Zahl der Fragen dürfte endlich sein, auch darum emfehlen wir hier das gute alte for(;;)-Konstrukt.
Natürlich ist sie endlich. Eigentlich ist es ja nur eine Frage. Sie wird einfach solange wiederholt, bis eine korrekte Antwort angegeben wurde.Dann ist while genau richtig. Denn while ist für Anweisungssequenzen bei denen vorab nicht klar ist, wie oft der Code ausgeführt werden soll bzw. wann die Abbruchbedingung erfüllt ist.
Eigentlich will ich ja auch bei der while bleiben, nur will ich sie nicht so aufrufen:
while(true)
{
}
Denn dann meckert Perl beim ausführen des Scriptes
Eigentlich will ich ja auch bei der while bleiben, nur will ich sie nicht so aufrufen:
while(true)
{
}
Sichwort: perlsyn
Entweder Du kommst mit Goto oder mit while(<Bedingung>){;} oder mit do ... while.
Schau doch mal in die oben benannte Doku.
Hey,
case gibts ja net
falsch. Steht sogar in der FAQ. http://perldoc.perl.org/perlfaq7.html#How-do-I-create-a-switch-or-case-statement%3F
Moin,
Hey,
case gibts ja net
falsch. Steht sogar in der FAQ. http://perldoc.perl.org/perlfaq7.html#How-do-I-create-a-switch-or-case-statement%3F
Danke für den Hinweis und den Link. Werd' mich da mal schlau machen.
Pot