Anzeige:
Ergebnis 1 bis 3 von 3

Thema: [Perl] Referenz auf Filehandels

  1. #1
    Registrierter Benutzer Avatar von Caveman
    Registriert seit
    03.11.2005
    Ort
    Geilsheim
    Beiträge
    308

    Question [Perl] Referenz auf Filehandels

    Hallo *,

    ich möchte in Perl einen Filehandler als Referenz abspeichern, da ich den in mehreren Funktionen brauche.

    So wie hier funktioniert es leider nicht
    Code:
    #!/usr/bin/perl -w
    
    use strict;
    use warnings;
    
    sub new                                     # Konstruktor
    {
      my $this  = shift;
      my $class = ref($this) || $this;
      my $path  = shift;
      my $name  = shift;
    
      my $self  = {
                  filehandler => \*DATA,
                  };
    
      bless $self, $class;
    
      open( $self->{filehandler}, "<$path$name" ) ||
          die "Datei " . $name . " kann nicht geoeffnet werden";
    
      return $self;
    }
    
    sub getLines                                # Zeilen einlesen
    {
      my $self = shift;
      my @line;
    
      while ( $self->{filehandler} )    #### funktioniert so nicht ####
      {
        s/#.+//;                                # Kommentare entfernen
        s/^\s+//;                               # Leerzeichen am Anfang entfernen
        s/\s+$//;                               # Leerzeichen am Ende entfernen
        if ( /^__END__/ )
        { # Ende des Datenbereichs erreicht
          last;
        }
        if ( /^./ )
        { # wenn Zeile nicht leer ist
          $line[++$#line] = $_;
        }
      }
    
      return \@line;
    }
    
    sub DESTROY                                 # Destruktor
    {
      my $self = shift;
    
      close( $self->{filehandler} );
    }
    
    my $fileRead = main->new("./", "testfile.txt");   # Konstruktor aufrufen
    my $lines    = $fileRead->getLines();             # Datei zeilenweise holen
    
    foreach my $line ( %{$lines} )
    {
      print "$line\n";                                # Ausgabe
    }
    
    1;
    
    __END__
    Wie mache ich es richtig?

    Edit:
    Auch mit dieser Zeile mag es nicht funktionieren:
    Code:
    while ( "<" . $self->{filehandler} . ">" )
    Geändert von Caveman (13-03-2006 um 11:03 Uhr)
    Programmiere (wenn es denn mal wieder vorkommt) in C, C++, Java, Perl
    Bin kein Student (Elektrotechnik) mehr und habe die Seiten gewechselt von der Software weg hin zur Hardware

  2. #2
    Registrierter Benutzer
    Registriert seit
    19.08.2004
    Beiträge
    404
    Hi,

    zunächst mal zum Konstruktor:

    PHP-Code:
    sub new                                     # Konstruktor
    {
      
    my $this  shift;
      
    my $class ref($this) || $this;
      
    my $path  shift;
      
    my $name  shift;

      
    my $self  = {
                  
    filehandler => \*DATA,
                  };

      
    bless $self$class;

      
    open$self->{filehandler}, "<$path$name) ||
          die 
    "Datei " $name " kann nicht geoeffnet werden";

      return 
    $self;



    filehandler => \*DATA, kannst du Dir sparen. Zum einen gibts ja noch garkein DATA, was Du zuweisen könntest, zum anderen initialisierst du $self->{filehandler} ja eh in der open() Anweisung... Es genügt also ein einfaches:

    PHP-Code:
    my $self  = {
      
    filehandler => undef
    }; 


    Um von dem Handle zu lesen benutzt Du die readline() Funktion... also


    PHP-Code:
    while(readline($self->{filehandler})
    {
      print;



    Sonst landest Du in einer Endlosschleife weil $self->{filehandler} ja wohldefiniert ist und auch bleibt...

    Was ich noch nicht verstanden habe, ist der Inhalt dieser while-Schleife.
    Wozu das zweidimensionale Array? Warum gibst Du eine Referenz auf das lokale Array zurück und warum derefenzierst Du später als Hash?

    Wenn Du nicht etwas ganz spezielles damit erreichen willst, dürfte folgendes wohl die syntaktisch korrektere Lösung sein:

    PHP-Code:
    my @line;
    while(
    readline($self->{filehandler}))
    {
      
    #tu was
      
    if ( /^./ )
      { 
    # wenn Zeile nicht leer ist
        
    push(@line$_);
      }
    }
    return(@
    line); 


    und

    Code:
    my @lines    = $fileRead->getLines();
    foreach(@lines)
    {
      print;
    }
    soweit, hth,

    Michael

  3. #3
    Registrierter Benutzer Avatar von Caveman
    Registriert seit
    03.11.2005
    Ort
    Geilsheim
    Beiträge
    308
    Danke, mit readline() funktioniert's

    Ich habe die Zeile
    filehandler => *DATA,
    ganz entfernt und habe in die while-Schleife
    readline($self->{filehandler})
    eingetragen.

    Zu dem war noch ein kleiner Fehler in der foreach-Schleife der Ausgabe:
    Hier muss natürlich statt diesem:
    foreach my $line ( %{$lines} )
    das:
    foreach my $line ( @{$lines} )
    stehen (Also Array statt Hash)

    Auch habe ich
    push(@line, $_);
    statt
    $line[++$#line] = $_;
    eingesetzt, was allerdings nichts ändert (funktioniert beides).

    Als Referenz geb ich das Array deshalb zurück, weil ich keine Kopie haben möchte.
    Die Daten werden in einer anderen Klasse noch weiter verarbeitet und dann in deren Klassenvariable abgelegt.
    Programmiere (wenn es denn mal wieder vorkommt) in C, C++, Java, Perl
    Bin kein Student (Elektrotechnik) mehr und habe die Seiten gewechselt von der Software weg hin zur Hardware

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •