Artikel im Internet unter http://www.hidemail.de/blog/bestimmte-anzahl-von-zeilen-aus-datei-einlesen---probleme-eines-lesers.shtml.
Montag, 3.9.2007, 14:58:30 Uhr

Bestimmte Anzahl von Zeilen aus Datei einlesen - Probleme eines Lesers



Ich habe heute per Email von den Problemen eines Lesers erfahren, der zehn Zeilen aus einer Datei einlesen will, was aber irgentwie nicht hinhaut.

Er hat mir auch gleich seinen Code mitgeschickt, der folgendermaßen aussieht:


open (my $IN, "<$filename");
my @array=();
my $cou=0;

while (<$IN>){
$array[$cou]=$_;
print "Zeile: $cou \n";
print "$array[$cou] \n";
sleep (1);
$cou++;
next if $cou < 10;

} # while-Scheife
close ($IN) ;


Die print's und das sleep sind nur zum debuggen gedacht...

Was läuft also schief, warum wird nach zehn Zeilen nicht abgebrochen?

Also, was passiert?
Die Datei wird geöffnet, ein Zähler wird initialisiert. Per while wird die Datei zeilenweise eingelesen, einem Array @array zugeordnet, der Zähler erhöht, und wenn der Zähler kleiner 10 ist (0-9 sind ja zehn Zeilen) dann wird per next die nächste Zeile eingelesen. So weit, so richtig, so gut!

Aber was passiert, wenn der Zähler auf => 10 steht?
Dann wird nicht per next die nächste Zeile eingelesen. Allerdings kommt hinter dem next ja gleich die abschließende Klammer des While-Befehles, was Perl so interpretiert, daß die Schleife weiter durchlaufen wird. Also wird nicht per next die nächste Zeile geholt, sondern durch das while, da ja noch Zeilen zum Einlesen da sind. Das while liest ja so lange ein, so lange noch was da ist, was eingelesen werden kann...

Was tun?

Naja, zwei Möglichkeiten, erst die Unsauberere:

open (my $IN, "<$filename");
my @array=();
my $cou=0;

while (<$IN>){
$array[$cou]=$_;
print "Zeile: $cou \n";
print "$array[$cou] \n";
sleep (1);
$cou++;
next if $cou < 10;
last;
} # while-Scheife
close ($IN) ;


Es wird per last; explizit angegeben, daß, falls nicht per next die nächste Zeile angefordert wird, die aktuelle Zeile die Letzte war. Oder die bessere Lösung (zumindest meiner Meinung nach...):

open (my $IN, "<$filename");
my @array=();

while (<$IN>){
$array[$.]=$_;
print "Zeile: $. \n";
print "$array[$.] \n";
sleep (1);
last if $. == 10;
} # while-Scheife
close ($IN) ;


Da durch das while die Datei sowieso automatisch komplett eingelsen wird, ist das next erstmal überflüssig.

Allerdings wird durch das

last if $. == 10;


die while-Schleife automatisch abgebrochen, wenn der Dateizeilen-Zähler $. (siehe hier und hier) auf 10 steht. Eine separater Counter ($cou) ist aber auch nicht schlecht, nur in dem Fall nicht nötig...
Eines vielleicht noch:
Beim Öffnen der Datei sollte man die Schreibweise

open (my $IN, '<'.$filename);


anwenden. Siehe diesen Artikel.
Ich hoffe, ich konnte das das Problem des Lesers anschaulich verdeutlichen und konnte ihm weiterhelfen. Und noch nen schönen Gruß in die Schweiz!


Artikel im Internet unter http://www.hidemail.de/blog/bestimmte-anzahl-von-zeilen-aus-datei-einlesen---probleme-eines-lesers.shtml.