Foreach vs. while

hallo zusammen!
ich hätte mal eine verständnisfrage:
ich habe hier ein flatfile mit rund 50 einträgen/zeilen, die etwas umsortiert werden- eine methode von bleibt auf der hälfte stecken und ich verstehe nicht ganz wieso.

der hänger ist diese hier:
open (FLAT, „flatfile.txt“);
@inhalt=;
foreach $zeile (@inhalt)
{…}

so läufts dagegen:
open (FLAT, „flatfile.txt“);
while ($zeile=)

wie gesagt: bei der foreach-variante ist nach 25 einträgen schluss- sieht zufällig jemand einen nachvollziehbaren grund dafür (oder ist das der elektrolurch)?
danach folgt übrigens ein split und je 2 teile werden in ein array geschoben…

gespannte grüße
bernd

Hallo Bernd!

open (FLAT, „flatfile.txt“);
@inhalt=;
foreach $zeile (@inhalt)
{…}

so läufts dagegen:
open (FLAT, „flatfile.txt“);
while ($zeile=)

bei der foreach-variante ist nach 25 einträgen
schluss- sieht zufällig jemand einen nachvollziehbaren grund
dafür (oder ist das der elektrolurch)?

Die Varianten müssten sich eigentlich gleich verhalten.
Der Zeileneingabeoperator gibt so lange Zeilen zurück,
bis das Dateiende erreicht ist. Das wird unter Windows mit dem
Dateiendezeichen STRG-Z (=Strg-Taste halten und Z drücken) simuliert.
Hast Du vielleicht so ein Zeichen in der Textdatei, welches ein
vorzeitiges Ende verursacht?

Hier ein Beispiel für das vorzeitige Abbrechen der Dateileseoperation:
Zuerst die präparierte Datei:

Z1: asdas
Z2: asdfk
Z3: STRG-Z
Z4: Du siehst mich nicht

Test-Skript:

#!c:/Perl/bin/perl -w --
use strict;
my $datei = "eof.txt";
print "foreach-Variante:\n";
open (FLAT, $datei);
#binmode FLAT;
my @inhalt=;
foreach my $zeile (@inhalt){
 print $zeile;
}
close(FLAT);

print "\nwhile-Variante:\n";
open (FLAT, $datei);
#binmode FLAT;
while (my $zeile=){
 print $zeile;
}
close(FLAT); 

Unter Windows wird die Zeile 4 bei beiden(!) Varianten nicht
ausgegeben. Das kannst Du vermeiden, indem Du binmode verwendest.

An welcher Stelle hört denn das Einlesen auf? Das müsste
doch immer die gleiche sein, oder? Veränderst Du die Zeilen
vielleicht vor der Schleife, z.B. per chomp oder chop?

Soviel zu meinen spontanen Ideen zum Problem …

Gruß,
-Andreas.

elektrolurch
hallo andreas!
besten dank für die gründliche bearbeitung :smile:
nun weiß ich, dass es wohl leider keine vernünftige erklärung für diese anomalie gibt…

Hast Du vielleicht so ein Zeichen in der Textdatei, welches
ein
vorzeitiges Ende verursacht?

mit ziemlicher sicherheit nicht, denn das flatfile wurde pikanterweise ebenfalls von einem perl-script generiert- und das ist *hüstel* clean :wink:
weswegen dies…

Unter Windows wird die Zeile 4 bei beiden(!) Varianten nicht
ausgegeben. Das kannst Du vermeiden, indem Du binmode
verwendest.

…leider auch nichts einbrachte. sei’s drum- danke dir trotzdem.

An welcher Stelle hört denn das Einlesen auf? Das müsste
doch immer die gleiche sein, oder?

das ist in der tat so, aber wie gesagt…

Veränderst Du die Zeilen
vielleicht vor der Schleife, z.B. per chomp oder chop?

nein, ich splitte anhand der tabs, mehr nicht.
was soll’s auch: ich nehme while und fertig. ich dachte halt, ich könnte vielleicht noch ein paar hintergründe lernen, aber das tu ich dann ein andermal :wink:

beste grüße
bernd

wenn du’s wirklich wissen willst …
Hi Bernd

ich dachte halt, ich könnte vielleicht noch ein paar hintergründe lernen

Stell die Frage mal (auf Englisch) bei den http://www.perlmonks.org
Die lieben solche Fragen und werden nicht ruhen bis sie die Antwort gefunden haben.

Pragmatisch weiterprogrammieren ist gut, aber den Fehler verstehen ist noch besser, denn sonst kommt er möglicherweise einige Zeilen (oder Wochen) später an anderer Stelle wieder daher geschlichen …

Gruß Ingo

Hi,

hallo zusammen!
ich hätte mal eine verständnisfrage:
ich habe hier ein flatfile mit rund 50 einträgen/zeilen, die
etwas umsortiert werden- eine methode von bleibt auf der
hälfte stecken und ich verstehe nicht ganz wieso.

der hänger ist diese hier:
open (FLAT, „flatfile.txt“);
@inhalt=;
foreach $zeile (@inhalt)
{…}

so läufts dagegen:
open (FLAT, „flatfile.txt“);
while ($zeile=)

Der einzige Unterschied hier scheint zu sein, dass du einmal alle Zeilen in einem Rutsch liest ( im array-context) und einmal nacheinander.

Ist die Datei vielleicht noch irgendwo anders geoeffnet? Oder sind die Zeilen seeehr lang? Welche Größe hat das array @inhalt? (print scalar(@inhalt)), oder versuch es mal mit den wunderbaren DataDumper:

use Data::smiley:umper;

open(FLAT,"flatfile.txt") or die $!;
@inhalt = ;
print Dumper(\@inhalt);

Ansonsten muesste man sich mal das Flatfile ansehen, um festzustellen, was da schief laeuft.

Dass gerade nach 25 Eintraegen Schluss sein soll ist auch auffaellig, schliesslich ist das ja gerade die Haelfte, wenn ich das richtig verstanden habe. Gibt es vielleicht noch irgendwo aendernde Zugriffe auf @inhalt innerhalb des Schleifenrumpfs?

Gruesse
kampi