Homepage Inspire-world | Forum
CGI/Perl Workshops Verschiedene Schleifenfunktionen foreach, for und while

 Inhaltsverzeichnis/Workshops Übersichtsseite/Verschiedene Schleifenfunktionen foreach, for und while
Vorwort
Die foreach Schleife
Die for Schleife
Die while Schleife
Die until Schleife
Schleifensteuerbefehle last, next und redo

Vorwort:

Die verschiedenen Schleifenfunktionen von Perl dienen dazu eine Anweisung solange auszuführen bis eine Bedingung erfüllt oder nicht erfüllt ist. Die häufigsten Einsatzbereiche sind das darstellen von Dateiinhalten, schreiben/ändern von Dateiinhalten, das versenden Von E-Mails uvam.

Ich werde hier einige Praxisbezogene Beispiele vorstellen.


Top
Die foreach Schleife

Grundsätzlicher Aufbau
foreach (Anweisungsblock) {
Ausführung der Anweisungen...
}
Dies Schleife gibt die Zeile "Ausgabe der Daten $zaehler" soviele male aus wie im Bereich 1..$wert angegeben. Deshalb nennt man den .. auch Bereichsoperator.
foreach $zaehler (1..$wert) {
print "Ausgabe der Daten $zaehler\n";
}
Beispiel 1, eine Texdatenbank auslesen
Daten werden oftmals in einem solchen Format gespeichert:
Name|Vorname|Telefon
Name|Vorname|Telefon
Name|Vorname|Telefon
...weitere Zeilen
Die Aufgabe besteht nun darin diese Datei auszulesen und das Array von Daten aufzusplitten und auszugeben.

open (DAT,"<daten.dat") or scripterror("Fehler: Kann daten.dat nicht oeffnen!",$!);
flock (DAT, 2);
@DATEI=<DAT>;
close (DAT);
print "<table border=\"1\">";

foreach $linien (@DATEI){
chomp($linien);
($name,$vorname,$telefon)=split(/\|/,$linien);
print "<tr><td>$name</td><td>$vorname</td><td>$telefon</td></tr>\n";
}
print "</table>";
Erläuterungen dazu:
foreach $linien (@DATEI){ Hier wird der Anweisungsblock definiert, also das was foreach tun soll. In dem Fall ist es so das hier alle Linien des Datei Arrays @DATEI durchlaufen werden sollen.

chomp($linien); chomp (engl. nagen) nimmt von jeder Linie das \n am Ende weg.

($name,$vorname,$telefon)=split(/\|/,$linien); Nun folgt das splitten der Linien in die einzelnen Bestandteile.

print "<tr><td>$name</td><td>$vorname</td><td>$telefon</td></tr>\n"; Diese Zeile "printet" dann die Inhalte der Datei in eine Tabellenzeile aus } beendet die Schleife


Beispiel 2, eine Texdatenbank umsortieren und Zeilennumern einfügen
Manchmal kann man ja in die Verlegenheit kommen einen Datensatz von einem Script zu einem anderen zu portieren. Ist hier die Datenstruktur eine andere muss man nicht mit Stundenlanger Handarbeit die Dateien ändern. Im folgenden Beispiel ist die Aufgabe den Datensatz von Beispiel 1 fortlaufend zu nummerieren und den Name an das Zeilenende zu stellen.

Vorher:
Name|Vorname|Telefon
Name|Vorname|Telefon
Name|Vorname|Telefon
...weitere Zeilen
Nacher:
1|Vorname|Telefon|Name
2|Vorname|Telefon|Name
3|Vorname|Telefon|Name
...weitere Zeilen
Das dazu nötige Script
open(F,"<daten.dat") or scripterror("Fehler: Kann daten.dat nicht oeffnen!",$!);
@linie=<F>;
close (F);

$total = 0; 
foreach $i (@linie) {
chomp($i);

($aa,$bb,$cc) = split(/\|/,$i);
$total++;

open(FI,">>daten1.dat") or scripterror("Fehler: Kann daten.dat nicht oeffnen!",$!);
print FI "$total|$bb|$cc|$aa\n";
close (FI);
}


Top
Die for Schleife

Grundsätzlicher Aufbau
For Schleifen können z.B. dazu benutzt werden um aus einer Textdatenbank nur einen bestimmten Bereich auszugeben.
for ( Anfangswert; Bedingungsausdruck; Änderung; ) {
Ausführung der Anweisungen...
}
In diesem Beispiel hier wird vom Startwert 0 aus solange die Zeile "Ausgabe der Daten $i" ausgegeben wie die Bedingung $i <= 10 nicht erfüllt ist. In Worten ausgedrückt könnte man sagen: "Fange mit 0 an und erhöhe den Wert um 1 ($i++) solange bis $i kleiner/gleich 10 ist."
for ($i = 0; $i <= 10; $i++) {
print "Ausgabe der Daten $i\n";
}
Beispiel 1, eine Texdatenbank Zeilenweise anzeigen
In diesem Beispiel wird eine Textdatenbank Zeilenweise angezeigt. Der Wert zum weiterzählen wird per Query String übergeben und hochgezählt. Anschließend wird durch eine Meta Refresh die Seite neu geladen mit dem um 1 erhöhten Wert. Sind alle Daten angezeigt worden wird eine Meldung ausgegeben.

Einsatzmöglichkeiten gibt es für derlei Schleifen einige. So könnte man ein selbständig weiterblätterndes "Bilderbuch" ausgeben, Dateien anlegen lassen oder ändern, einzelne Datensätze ausgeben lassen uvam.
#!/usr/bin/perl

#Fehlerausgabe an Browser
use CGI::Carp qw(fatalsToBrowser);
# Content Typ ausgeben
print "Content-type: text/html\n\n";

# Wert des Query Strings auslesen
$wert = $ENV{'QUERY_STRING'};

# Datei öffen und auslesen
open (DAT,"<daten.dat") or scripterror("Fehler: Kann daten.dat nicht oeffnen!",$!);
flock (DAT, 2);
@daten=<DAT>;
close (DAT);
chomp(@daten);

# Wert 2 um 1 erhöhen
# Notiert man bei $wert2 = $wert + 1; nicht 1 sondern z.B. 10 werden
# also immer 10 Zeilen der Textdatenbank ausgegeben
$wert2 = $wert + 1;
# Wenn Wert leer ist Startwert 0 zuweisen
if ($wert eq "") {
$wert = 0;
}

# Die Schleifenfunktion
# Arbeitsweise:
# Startwert $wert ist 0 oder das was per Query String übergeben wurde
# $wert2 ist $wert + 1, also wird nur eine Zeile hochgezählt bei $i++
for($i=$wert;$i<$wert2;$i++) {
# Splitten der Zeile
($name,$vorname,$tel) = split(/\|/, $daten[$i]);
chomp($tel);

# Wenn Zeile nicht leer ist...
if ($name ne "") {

# printe Zeile...
print "$name - $vorname - $tel";

# Zeile für Metarefresh ausgeben
print "<meta http-equiv=\"refresh\" content=\"2; URL=script.pl?$wert2\">";

# Ende erreicht? Meldung ausgeben das alles angezeigt wurde
} else {
print "Alle Daten angezeigt";
}
}



Top
Die while Schleife

Grundsätzlicher Aufbau
while (Bedingungsausdruck) {
Ausführung der Anweisungen...
}
While Schleife mit "Zähler"
$start = 0;
while ($start <= 10) {
print "Ausgabe der Daten $start\n";
$start++;
}
Beispiel 1, Passwortdatei auslesen und Schleife bei Treffer abbrechen.
Hier in dem Beispiel geht es darum eine Datei mit Usernamen und Passwörtern auszulesen. Die Schleife soll dabei abgebrochen werden wenn die Bedingung erfüllt ist. Dazu wird der Befehl last; eingesetzt.

Die Arbeitsweise der Schleife im Detail:

1. Zu Beginn ist $gefunden = 0; - heisst kein Treffer

2. Nun wird die Schleife durchlaufen und wenn die Daten gefunden wurden/übereinstimmen der Wert von $gefunden = 1; auf 1 gesetzt. Mit last wird die Schleife sofort abgebrochen.
$gefunden = 0;
open(DATEI, "<userdaten.dat") or scripterror("Fehler: Kann userdaten.dat nicht oeffnen!",$!);
flock(DATEI, 2);
while ($linie = <DATEI>) {
chomp($linie);
($username,$userpasswort) = split(/\|/, $linie);
if ($user eq $username && $password eq $userpassword) {
$gefunden = 1;
last;
}
}
close(DATEI);
Nun kann mittels des zurückgegebenen Wertes von $gefunden reagiert werden auf den Schleifendurchlauf.

Wurde nichts gefunden !$gefunden - das ! vor $gefunden heisst soviel wie Wert falsch oder nicht vorhanden, wird die Subroutine &loginfehler; aufgerufen.
if (!$gefunden) {
&loginfehler;
exit;
} else {
Andernfalls können hier die Userdaten oder der Programmcode ausgegeben werden zu dessen Ausführung der User berechtigt ist.
}



Top
Die until Schleife

Grundsätzlicher Aufbau
until (Bedingungsausdruck) {
Ausführung der Anweisungen...
}
Until ist das Gegenteil von while. Bei einer while Schleife wird solange die Schleife abgearbeitet wie der Bedingungsaudruck wahr ist. Until führt die Schleife solange aus wie der Bedingungsausdruck falsch ist.


Top
Schleifensteuerbefehle last, next und redo

Grundsätzliches
Schleifensteuerbefehle wie last, next und redo kommen in for und while Schleifen zum Einsatz. Diese Befehle dienen dazu den normalen Schleifendurchlauf zu unterbrechen und je nach Befehl etwas zu tun.

1. last
Die Schleife wird sofort abgebrochen und weiterer Scriptcode ausgeführt

2. next
Die Schleife wird sofort abgebrochen und wieder zurück zum Anfang der Schleife gesprungen.

3. redo
Die Schleife wird sofort abgebrochen und wieder zurück zum Anfang der Schleife gesprungen. Hier wird aber nicht wie bei next der Bedingungsausdruck am Schleifenanfang ausgewertet, oder bei for Schleifen die Änderungsanweisung ausgeführt.




Top

 Zum Inhaltsverzeichnis/Workshops Übersichtsseite/Verschiedene Schleifenfunktionen foreach, for und while
Autor: Helmut Walter Homepage Inspire-world Fragen, Anregungen und Hinweise bitte in das Forum

Valid HTML 4.0! Valid CSS!