Moritz: Perl erzeugt beim Speichern ungewollte Zeilen

Hallo,
folgender Perl-Code hinterlässt beim Ausführen immer eine leere Zeile am Ende der Datei. Wie kann ich das verhindern?
Der Code soll einen Eintrag mit einer bestimmten ID aus der Datei löschen. Liegt dieser Eintrag irgendwo in der Mitte der Datei, gibt es keine Probleme, wird hingegen der letzte Eintrag gelöscht, bleibt am Ende immer eine leere Zeile über, die beim späteren Wiedereinlesen der Daten Probleme macht.

open(DATEI,"</Users/powermac/Sites/Praxisbedarf/data/database.txt") || die "Fehler beim &ouml;ffnen der Datenbank, Fehlercode 1 ";

#####################
#!/usr/bin/perl -w

use strict;
use CGI;
my $cgi = new CGI;
use CGI::Carp qw(fatalsToBrowser);

my $id = $cgi->param('id');
my @zeilen;
my @eintrag;
my $anzahl;

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Praxisbedarf | Eintrag &auml;ndern</title>
<script type='text/javascript'>
<!--
//-->
</script>
</head><body>\n";
if(($id eq "")) {
 print "<p>Bitte kontrollieren Sie Ihre Eingaben.</p>";
}
else {
open(DATEI,"</Users/powermac/Sites/Praxisbedarf/data/database.txt") || die "Fehler beim &ouml;ffnen der Datenbank, Fehlercode 1 ";
@zeilen = <DATEI>;
close(DATEI);

$anzahl = @zeilen;

for(my $i=0;$i<$anzahl;$i++) {
 @eintrag = split(/<>/,@zeilen[$i]);
 if(@eintrag[0] == $id) {
  splice(@zeilen,($i),1);
 }
}

print DATEI @zeilen;
close(DATEI);

print "<p>Der Eintrag mit ID $id wurde erfolgreich gel&ouml;scht!";
}
print "</body></html>";
#########################
Habt ihr eine Idee?

  1. Hell-O!

    folgender Perl-Code hinterlässt beim Ausführen immer eine leere Zeile am Ende der Datei. Wie kann ich das verhindern?

    Kennst du die Funktion chomp?

    Der Code soll einen Eintrag mit einer bestimmten ID aus der Datei löschen. Liegt dieser Eintrag irgendwo in der Mitte der Datei, gibt es keine Probleme, wird hingegen der letzte Eintrag gelöscht, bleibt am Ende immer eine leere Zeile über, die beim späteren Wiedereinlesen der Daten Probleme macht.

    Ein paar Hinweise zum Script seien mir gestattet:

    use strict;

    # für die Entwicklungsphase  
    use warnings;
    

    my $id = $cgi->param('id');

    Prüfe jede Eingabe auf ihre Gültigkeit (siehe perlsec)! Die Methode param() unterscheidet nicht nach GET oder POST.

    my @zeilen;
    my @eintrag;
    my $anzahl;

    Letztere ist überflüssig.

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Praxisbedarf | Eintrag &auml;ndern</title>

    Wenn du das CGI-Modul nutzt, warum dann nicht auch die Funktionen für die Ausgabe von HTML?

    if(($id eq "")) {
    print "<p>Bitte kontrollieren Sie Ihre Eingaben.</p>";
    }

    Das reicht als Prüfung nicht aus (s.o.).

    open(DATEI,"</Users/powermac/Sites/Praxisbedarf/data/database.txt") || die "Fehler beim &ouml;ffnen der Datenbank, Fehlercode 1 ";
    @zeilen = <DATEI>;
    close(DATEI);

    Warum untersuchst du die Datei nicht gleich beim Einlesen:

    open DATEI, $name or die "Error: $!";  
    my @neue_daten;  
    while(<DATEI>) {  
      next if ($_ =~ /$id/);  
      push @neue_daten, chomp($_);  
    }  
    close DATEI;
    

    Dann kannst du @neue_daten wegschreiben.

    print DATEI @zeilen;

    Das letzte Element enthält vermutlich ein Newline am Ende, deshalb die neue Zeile.

    Siechfred

    --
    Hier könnte Ihre Werbung stehen.
    Das Steuer-Blog | Siechfreds Tagebuch
    1. Moin.

      Und noch ein Kommentar vom mir:

      open DATEI, $name or die "Error: $!";
      close DATEI;

      Dann kannst du @neue_daten wegschreiben.

      Du solltest geeignete Maßnahmen ergreifen, die verhindern, daß zum einen während des Lesens und bearbeitens ein anderer die Datei schreiben darf und zum anderen zw. Öffnen, Lesen und Bearbeiten der Datei und dem Schreiben der geänderten Datei keine anderen User die Datei bearbeiten können.

      Stichwort flock, seek und truncate.

      Meine Empfehlung:
      open (zum lesen _und_ schreiben)
      flock
      Zeilen lesen und id löschen
      seek (Dateizeiger auf Anfang)
      truncate (alten Inhalt der Datei löschen)
      schreiben (neuer Inhalt)
      close

      Und vor dem close KEIN unlock der Datei, das passiert automatisch bei close.

      Gruß Frank

      1. Hell-O!

        Du solltest geeignete Maßnahmen ergreifen, die verhindern, daß zum einen während des Lesens und bearbeitens ein anderer die Datei schreiben darf und zum anderen zw. Öffnen, Lesen und Bearbeiten der Datei und dem Schreiben der geänderten Datei keine anderen User die Datei bearbeiten können.

        Ich wusste, dass ich wieder irgendwas vergessen habe :-)

        Siechfred

        --
        Hier könnte Ihre Werbung stehen.
        Das Steuer-Blog | Siechfreds Tagebuch
    2. Kennst du die Funktion chomp?

      wenn ich einfach
      chomp(@zeilen);
      anwende, sind aber alle newline Zeichen entfernt und ich will ja nur das am Ende weghaben...

      1. Kennst du die Funktion chomp?

        wenn ich einfach
        chomp(@zeilen);
        anwende, sind aber alle newline Zeichen entfernt und ich will ja nur das am Ende weghaben...

        du musst sie halt wieder einfügen:
        join "\n", @zeilen;

        Struppi.

        --
        Javascript ist toll (Perl auch!)