Datei mit TK-Modul einlesen
thomas
- perl
Hallo!
Wer kann mir sagen, wie ich in nachfolgendem Skript eine Datei einlesen kann. Es soll der Name der Datei unter "Ausgangsdatei" eingegeben werden und dann nach anklicken des Button "einlesen" die entsprechende Datei eingelesen werden. Funzt irgendwie nicht so, wie ich mir das gedacht habe:
use strict;
use Tk;
my $haupt = new MainWindow;
my $links = $haupt->Frame();
$links->Label(-text => "Ausgangsdatei:")->pack();
my $ausgang=$links->Entry();
$ausgang->pack();
my $schalter=$links->Button(-text => "einlesen",
-command => &einlesen
)->pack();
$links->Label(-text => "Ausgabedatei:")->pack();
my $ausgabe=$links->Entry();
$ausgabe->pack();
my $schalter1=$links->Button(-text => "schreiben",
-command => &schreiben
)->pack();
my $schalter2=$links->Button(-text => "beenden",
-command => [$haupt=>'destroy']
)->pack(-pady => "40");
my $rechts = $haupt->Frame();
$rechts->Label(-text => "Meldung:")->pack();
my $meldung = $rechts -> Listbox();
$meldung -> pack();
$links->pack(-side=>"left");
$rechts->pack(-side => "right", -side =>"top", -padx=>"50");
MainLoop();
sub einlesen {
open (AUSGANG, "$ausgang")
or die "Datei kann nicht geoeffnet werden!\n";
}
Hi,
my $links = $haupt->Frame();
$links->Label(-text => "Ausgangsdatei:")->pack();
my $ausgang=$links->Entry();
$ausgang->pack();
Der Code wird gleich zu Anfang ausgeführt, wenn der User noch gar keine Chance hatte, was einzugeben oder auszuwählen. Verlege den besser nach &einlesen.
sub einlesen {
open (AUSGANG, "$ausgang")
or die "Datei kann nicht geoeffnet werden!\n";
}
Da fehlt jetzt noch der Code, um Text einzulesen. Bis hierhin hast du nur die Datei aufgemacht.
while (<AUSGABE>){
#Dann sowas wie
$ausgabe->text.=$_;
#kenn mich mit Tk nicht so aus, siehe Doku...
}
und natürlich ein
close AUSGABE;
HTH
wunderwarzenschwein
hallo thomas,
my $schalter=$links->Button(-text => "einlesen",
-command => &einlesen
)->pack();
Ich bin mir nicht sicher, ob der Zeiger zur Subroutine so funktioniert, kann aber sein.
sub einlesen {
open (AUSGANG, "$ausgang")
or die "Datei kann nicht geoeffnet werden!\n";
}
Deine Subroutine ist allerdings mehr als unvollständig. $ausgang wird zwar geöffnet, sofern vorhanden, aber dann machst du nichts weiter damit. Wenn das "ausgegeben" werden soll, müßtest du die Datei beispielsweise in einen Array einlesen und den danach zeilenweise mit print wieder ausgeben lassen. Das ist im Prinzip alles, und falls deine diversen Variablen funktionieren (ich bin nicht sicher, ob die alle sein müssen), sollte das Ganze auch klappen.
Perl liefert dir ganz zuverlässige Fehlermeldungen. Was hast du denn im log stehen?
Grüße aus Berlin
Christoph S.
Ich weiß, dass die Subroutine mehr als unvollständig ist. Mein Problem liegt darin, dass ich es nicht hinbekomme, die Datei einzulesen, dann wieder zu verändern und neu auszugeben.
Das ganze Ding ist für eine EDV-Weiterbildung, in der u. a. Perl behandelt wird. Aufgabenstellung: Es soll mittels TK-Modul eine Text-Datei vom Benutzer eingegeben werden. Diese soll dann eingelesen, mit Zeilennummern versehen werden und wieder neu geschrieben werden. Dann soll noch eine ok-Meldung in einer Listbox erscheinen.
Nunja, das Problem ist, dass ich nicht mit dem Einlesen der Datei zurechtkomme, alles weitere würde sich dann zeigen - oder auch nicht :-)
Nicht dass ich hier falsch verstanden werde, ich will keine komplette Lösung, denn ich soll ja schließlich auch was lernen. Wäre aber trotzdem nett, wenn mir ein wenig beim "einlesen der Datei mittels Array" auf die Sprünge helfen könnte.
Danke.
hallo,
Ich weiß, dass die Subroutine mehr als unvollständig ist. Mein Problem liegt darin, dass ich es nicht hinbekomme, die Datei einzulesen, dann wieder zu verändern und neu auszugeben.
Dann schauen wir doch nochmal drauf:
sub einlesen {
open (AUSGANG, "$ausgang")
or die "Datei kann nicht geoeffnet werden!\n";
Bis dahin ist das in Ordnung, lediglich der Zeilenumbruch ist möglicherweise nicht zwingend erforderlich. Du kannst jetzt mit
my @anzeige = <AUSGANG>;
den gesamten Inhalt der geöffneten Datei in diesen Array @anzeige (Name ist frei wählbar) packen. Und falls du den ganzen Kram jetzt lediglich wieder ausgeben willst, machst du das zum Beispiel so:
foreach my $zeile (@anzeige) {
print $zeile;
Du kannst den Array natürlich noch splitten oder mit RegExpressions bearbeiten usw. Ist eigentlich gar nicht so schwer, und wenn man die PERL-Kapitel in SELFHTML aufmerksam liest, bekommt man es dort auch erklärt.
Natürlich müssen alle Klammern wieder geschlossen werden, und zuletzt darf, wie bereits im Thread angemerkt, ein
close(AUSGANG);
nicht fehlen.
Das Ganze wird dir aber nix nutzen, falls deine Variable $ausgang keinen Wert haben sollte, und der Weg, auf dem sie einen Wert (deine zu öffnende Datei) erhalten soll, ist für mich nicht vollständig nachvollziehbar - aber das habe ich bereits geschrieben. Ich habe auch nicht ganz umsonst nach den Server-logs gefragt, da sollte, falls du fehlerhaft gearbeitet hast, einiges an Erklärung drinstehen.
Aufgabenstellung: Es soll mittels TK-Modul eine Text-Datei vom Benutzer eingegeben werden. Diese soll dann eingelesen, mit Zeilennummern versehen werden und wieder neu geschrieben werden. Dann soll noch eine ok-Meldung in einer Listbox erscheinen.
Hm. Soll das über eine Netzwerkverbindung (also über HTTP und einen Webserver) geschehen? Wie erhält denn der "user" dein GUI auf seinen Bildschirm?
Grüße aus Berlin
Christoph S.
@Christoph
Nein, das ganze soll nicht über eine Netzwerkverbindung laufen, sondern lediglich durch Aufruf in der Konsole. Habe es nach langem hin- und her dann doch noch hinbekommen :-)
Man tut sich halt recht schwer als Anfänger. Hab hier nochmal den kompletten, funktionierenden Code gepostet, falls es jemanden interessieren sollte:
#!e:/perl/Perl/bin/perl -w
use strict;
use Tk;
my $haupt = new MainWindow;
my $links = $haupt->Frame();
$links->Label(-text => "Ausgangsdatei:")->pack();
my $eingang=$links->Entry();
$eingang->pack();
$links->Label(-text => "Ausgabedatei:")->pack();
my $ausgang=$links->Entry();
$ausgang->pack();
my $schalter=$links->Button(-text => "ausfuehren",
-command => &einlesen
)->pack(-pady => "20");
my $schalter2=$links->Button(-text => "beenden",
-command => [$haupt=>'destroy']
)->pack(-pady => "40");
my $rechts = $haupt->Frame();
$rechts->Label(-text => "Meldung:")->pack();
my $meldung = $rechts -> Listbox();
$meldung -> pack();
$links->pack(-side=>"left");
$rechts->pack(-side => "right", -side =>"top", -padx=>"50");
MainLoop();
sub einlesen {
my $nummer = 0;
my $eingang_sub = $eingang -> get;
my $ausgang_sub = $ausgang -> get;
open (EINGANG, "< $eingang_sub");
open (AUSGANG, "> $ausgang_sub");
while (my $zeile=<EINGANG>){
$nummer++;
my $zeile_mit_nummer = $nummer." ".$zeile;
print AUSGANG $zeile_mit_nummer;
}
close(EINGANG);
close(AUSGANG);
$meldung->insert('end', "Ausfuehrung erfolgreich.");
}
Danke für Deine Hilfe.
Gruß aus dem Westerwald nach Berlin.
Thomas
guten Abend,
Habe es nach langem hin- und her dann doch noch hinbekommen :-)
Gratuliere. Und wie ich sehe, hast du deine Subroutine "einlesen" stark verändert, teilweise in der Richtung, die ich dir vorgeschlagen habe.
Ja, so _kann_ das funktionieren, hat allerdings noch einen Schönheitsfehler. Selbstverständlich kannst du bei Bedarf mit "open" irgendwas zum Lesen oder Schreiben, zum Dranhängen oder Rauslöschen ganz nach Belieben öffnen, und es dürfen auch mehrere solche "open"-Anweisungen direkt nacheinander notiert werden - auf das Funktionieren deines Scripts sollte das so gut wie keinen Einfluß haben. Trotzdem ist es nicht ganz korrekt. Überlege dir genau, wann du eine geöffnete Datei wieder schließen solltest - das sollte möglichst rasch geschehen. Und anstelle deines "while" würde ich eher mit "for" oder eben "foreach" arbeiten.
sub einlesen {
my $nummer = 0;
my $eingang_sub = $eingang -> get;
my $ausgang_sub = $ausgang -> get;open (EINGANG, "< $eingang_sub");
open (AUSGANG, "> $ausgang_sub");while (my $zeile=<EINGANG>){
$nummer++;
my $zeile_mit_nummer = $nummer." ".$zeile;
print AUSGANG $zeile_mit_nummer;
}close(EINGANG);
close(AUSGANG);$meldung->insert('end', "Ausfuehrung erfolgreich.");
}
So _ganz_ zufrieden wäre ich damit noch nicht.
Danke für Deine Hilfe.
Bittesehr. Und ich hoffe, du hast verstanden, weshalb ein Thread, der hier im Forum begonnen wird, auch hier im Forum zu Ende diskutiert werden soll, und nicht per mail.
Grüße aus Berlin
Christoph S.
Ja, habe das verstanden. so können halt auch andere, die ggf. ein ähnliches Problem haben, den Lösungsweg mitverfolgen. weiß für's nächste mal Bescheid :-)