Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]12278[/thread]

korrektes Auslesen von Daten aus einem File



<< >> 5 Einträge, 1 Seite
ajcountry
 2008-07-31 16:26
#112943 #112943
User since
2008-07-22
4 Artikel
BenutzerIn
[default_avatar]
Hi,

bin ein kleiner noob im Bereich Perl, da ich grad damit anfange und habe ein Problem mit dem korrekten Auslesen von Daten aus einem File.

Der Aufbau des Files sieht wie folgt aus:

.
.
.
[Wertetabelle1]
|
[Zeile]
A1 3.227
A2 1.127
A3 -1.471
[Zeile]
B1 6.684
B2 1.054
B3 6.967
B4 4.008
[Zeile]
C1 2.757
C2 -3.192
C3 -2.820
[Zeile]
D1 4.245
D2 3.973
|
[Wertetabelle2]
|
[Zeile]
A1 3.227
A2 1.127
A3 -1.471
[Zeile]
B1 6.684
B2 1.054
B3 6.967
B4 4.008
[Zeile]
C1 2.757
C2 -3.192
C3 -2.820
[Zeile]
D1 4.245
D2 3.973
|
.
.
.


Mein Quelltext zum Auslesen des Files:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/perl

use strict;

   my $line;
   my @words;
   my @liste;
   my $i;

   _schreibeWerte();

sub _schreibeWerte
{
   open(FILE, "<bla.txt")
   or die "cannot open bla.txt";

 while($line=<FILE>)
 {
     if($line =~ /\[Wertetabelle1\]/ ){ $line=_Wertetabelle();}
     if($line =~ /\[Wertetabelle2\]/ ){ $line=_Wertetabelle();}
  }
  close(FILE);
}

sub _Wertetabelle
{
   while($line=<FILE>)
   {
     if($line =~ /\[Zeile\]/)
     {
       for($i=0;$i<=50;$i++)
       {
         $line=<FILE>;
         ## Einlesen der Werte in den Array
         @words = split /\s+/,$line;
         push(@liste, $words[1]);
         
         if($line =~ /\[Zeile\]/ ) {last;} 
   print $line;
      }
       if($line =~ /\[Wertetabelle1\]/ ) {  last;}
       if($line =~ /\[Wertetabelle2\]/ ) {  last;}
     }
   }
     return $line;
}


In dem Unterprogramm sub _schreibeWerte() lese ich das File aus und suche nach den Wörtern [Wertetabelle1] bzw. [Wertetabelle2]. Wenn er eines der beiden gefunden hat, soll er in das Unterprogramm sub _Wertetabelle springen.
Das funktioniert soweit.

In dem Unterprogramm sub _Wertetabelle möchte ich dann die darauffolgende [Zeile] suchen. Nach einer [Zeile] kommt definitiv ein oder mehrere Werte. Um mehrere Werte einlesen zu können benötige ich eine Schleife. Deswegen die for-Schleife. In der for-Schleife soll der nächste Wert eingelesen werden (da wo die Zahl drin steht) und von dem Index (A1, A2, usw. abgetrennt werden. Danach speichere ich diese in ein Array (@liste). Da mehrere Werte eingelesen werden müssen, nutze ich als Abbruchkriterium [Zeile]. Sobald alle Zeilen der Wertetabelle1 eingelesen wurden, breche ich mit [Wertetabelle1] ab.

Das Problem was ich habe das sobald er die Abbruchbedingung [Zeile] gefunden hat die nächsten Werte überspringt (B1,B2,B3,B4 bzw. D1,D2) und erst wieder die nächsten Werte ausgibt. Ebenfalls gibt er mir auch die Werte von Wertetabelle2 aus, was sicher daran liegt, dass die Abbruchbedingung nicht funktioniert.
Wie kann ich erreichen, dass er mir alle Werte für die jeweilige Wertetabelle ausgibt?

Vielen Dank schon mal für die Hilfe.

Gruß, André
moritz
 2008-07-31 16:43
#112945 #112945
User since
2007-05-11
923 Artikel
HausmeisterIn
[Homepage]
user image
Ich denke du machst es dir unnötig schwer. Durch das auftrennen des Lesens aus der Datei in verschiedene Subs ist es schwer zu erkennen, was wo genau passiert.

Ich hab mal ein Beispiel geschrieben, wie ich das ganze in eine verschachteltes Array packen würde:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @tables;

while (<DATA>){
    chomp;
    next if m/^\|/;
    if (m/^\[Wertetabelle\d\]/){
        # neue Tabelle anlegen
        push @tables, [];
    } elsif (m/^\[Zeile\]/) {
        # neue Zeile anlegen
        push @{$tables[-1]}, [];
    } else {
        # Daten reinschaufeln:
        push @{$tables[-1][-1]}, [split];
    }
}
print Dumper \@tables;


__DATA__
[Wertetabelle1]
|
[Zeile]
A1 3.227
A2 1.127
A3 -1.471
[Zeile]
B1 6.684
B2 1.054
...


Ich vermute, dass das Problem mit deinem Lösungsansatz ist, dass du in der while-Schleife eine Zeile liest, und die in der for-Schleife nicht weiterverwendest sondern einfach eine neue Zeile ausliest.
ajcountry
 2008-07-31 19:07
#112951 #112951
User since
2008-07-22
4 Artikel
BenutzerIn
[default_avatar]
Vielen Dank für deine schnelle Antwort.

Ich weiß, das es unnötig schwer ist, es in verscheidene Unterprogramme aufzutrennen, nur muss ich die Auftrennung in Unterprogramme leider vornehmen.
Da komm ich nicht drum herum! Wäre für weitere Hilfe sehr dankbar!
moritz
 2008-07-31 19:11
#112952 #112952
User since
2007-05-11
923 Artikel
HausmeisterIn
[Homepage]
user image
ajcountry+2008-07-31 17:07:22--
Da komm ich nicht drum herum! Wäre für weitere Hilfe sehr dankbar!


Ich hab dir unten auch noch geschrieben, was das Problem mit deiner Version ist. Denk darüber nach, es ist nich so wahnsinnig schwer zu beheben.
ajcountry
 2008-07-31 19:23
#112953 #112953
User since
2008-07-22
4 Artikel
BenutzerIn
[default_avatar]
Ja das ist auch der Knackpunkt.

in Zeile 39 sucht er nach [Zeile] welcher dann in $line steht.
Diesen Inhalt muss ich mir irgendwie merken und für die if Anweißung in Zeile 30 zur Verfügung stellen, das klappt mit der return Anweißung. Nur habe ich es noch nicht hinbekommen, wo genau mein Fehler liegt. Stehe mitlerweile voll auf dem Schlauch. :(
<< >> 5 Einträge, 1 Seite



View all threads created 2008-07-31 16:26.