Perl erzeugt beim Speichern ungewollte Zeilen
Moritz
- perl
1 Siechfred1 agapanthus0 Moritz0 Struppi
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 ö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 ä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 ö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öscht!";
}
print "</body></html>";
#########################
Habt ihr eine Idee?
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 ä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 ö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
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
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
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...
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.