![]() |
Textfiles Verständnisfrage & Frage
Hallo DPler,
Ich möchte gerne eine Variable mit Integerwert, also zb. einfach 14 extern in einer Textdatei speichern. Dazu habe ich folgende Prozedur entwickelt:
Delphi-Quellcode:
Dabei soll erst geschaut werden ob es die Datei schon gibt. Wenn ja wird in der Datei der Integerwert rausgelesen und in GesH gespeichert. Anschließend wird GesZ mit GesH addiert und in GesZ gespeichert.
procedure TForm1.Speichern;
var Speicher: Textfile; GesH:Integer; begin Try Reset(Speicher,'Speicher.txt'); Readln(Speicher,GesH); GesZ:=GesH + GesZ; Except AssignFile(Speicher,'Speicher.txt'); End; Rewrite(Speicher); Writeln(Speicher,GesZ); CloseFile(SPeicher); end; Wenn keine datei mit dem Namen Speicher.txt existiert soll in der except schleife eine erstellt werden. Anschließend wird der Zeiger auf ganz oben gestellt, das neue GesZ bzw. das existierende in der 1. zeile gespeichert, und dann geschlossen. Sind meine Überlegungen richtig? denn es gibt 1 komischen Fehler: 1. Wenn keine Datei existiert, wird mir trotzdem ein Fehler angezeigt, das die Datei nicht gefunden wurde, aber eigentlich müsste doch durch AssignFile eine erstellt werden? :?: |
AW: Textfiles Verständnisfrage & Frage
Welche Delphi-Version verwendest du?
|
AW: Textfiles Verständnisfrage & Frage
FreePascal/Lazarus?
Delphi kennt kein derartigen Reset-Befehl (in der System.pas) Zitat:
Fehler/Denkfehler:
|
AW: Textfiles Verständnisfrage & Frage
Interessant wäre auch: Wo landet die Datei ohne Pfad Angabe? :roll:
|
AW: Textfiles Verständnisfrage & Frage
Zitat:
Zitat:
|
AW: Textfiles Verständnisfrage & Frage
|
AW: Textfiles Verständnisfrage & Frage
@Klaus01
Niemand hat behauptet, dass es
Delphi-Quellcode:
in Delphi nicht gibt.
Reset
himitsu hat gesagt, dass es allerdings kein
Delphi-Quellcode:
gibt, dass so
Reset
Delphi-Quellcode:
aufgerufen werden kann. ;)
Reset( Speicher, 'Speicher.txt' );
|
AW: Textfiles Verständnisfrage & Frage
Ahh, so schnell so viele Antworten :shock: :-D
Also: @Uwe Raabe, Hier ein Ausschnitt von der Info über Borland Delphi: "Borland® Delphi® für Microsoft® Windows™ Version 10.0.2288.42451 Update 2 Copyright © 2005 Borland® Software Corporation." -> Also Version 10 !? @himitsu, Sry, das war viel zu oberflächlich der Fehler: Das Programm lässt sich mit dem Debugger einwandfrei starten, Erst wenn die Prozedur ausgeführt wird, Kommt eine Infobox, wo ich das Programm Anhalten,Fortsetzen kann mit der Meldung: "Im Projekt Project1.exe ist eine Exception der KLasse EInOutError mit der Meldung "Datei nicht gefunden" aufgetreten." -> Also eine Benachrichtigung über die Debugger-Exception?! Verstehe ich das richtig, dass ich nicht die Try-Except-Schleife verwenden kann? -> Muss ich dann eher eine If Fileexists=True then ... -Schleife verwenden? @Luckie, Also so wie ich das immer überlege müsste sie in dem Ordner, wo sich die .Exe befindet, erstellt werden. Dachte ich mir immer jedenfalls ^^. @Klaus01, Also kopiere ich einfach den Code aus dem Beispiel und bastel ihn in bei mir mit rein? @Sir Rufo, Warum kann das Reset nicht so
Delphi-Quellcode:
aufgerufen werden?
Reset(Speicher,'Speicher.txt')
|
AW: Textfiles Verständnisfrage & Frage
Weil die Dokumentation das sagt?
Delphi: ![]() FPC: ![]() |
AW: Textfiles Verständnisfrage & Frage
@Sir Rufo, okey, also einfach nur
Delphi-Quellcode:
? Aber das verstehe ich jetzt nicht :D Oder doch... also dann ändere ich jetzt den Code zu:
Reset(Speicher)
Delphi-Quellcode:
Okey, mit AssignFile weise ich also der Variablen Speicher einfach Speicher.txt zu?! Und wie kann ich jetzt eine Text Datei erstellen? o.0
procedure TForm1.Speichern;
var Speicher: Textfile; GesH:Integer; begin GesH:=0; AssignFile(Speicher,'Speicher.txt'); Reset(Speicher); Readln(Speicher,GesH); GesZ:=GesH + GesZ; Rewrite(Speicher); Writeln(Speicher,GesZ); CloseFile(SPeicher); end; |
AW: Textfiles Verständnisfrage & Frage
Müsste Delphi 2005 oder 2006 sein.
Exceptions sind Ausnahmen und keine Schleifen. Man sollte try-finally Blöcke benutzen, um Resourcen zu schützen, try-except Blöcke um spezielle Exceptions zu behandeln, aber nicht um ALLE Exceptions zu "verschlucken". Dein Code sollte ungefähr so aussehen:
Delphi-Quellcode:
Erklärung:
var
Speicher: Textfile; GesH: Integer; begin AssignFile(Speicher, 'Speicher.txt'); {$I-} Reset(Speicher); {$I+} try if IOResult = 0 then Readln(Speicher, GesH) else GesH := 0; // oder sonstiger Standardwert GesZ := GesH + GesZ + 1; Rewrite(Speicher); Writeln(Speicher, GesZ); finally CloseFile(Speicher); end; Du musst zuerst per AssignFile der Textfile-Variable den Dateinamen zuweisen. Sonst geht gar nichts. Du kannst ja auch nicht mit dem Auto losfahren, ohne vorher den Motor anzulassen. Per {$I-} wird der Compiler angewiesen, keine Exceptions zu generieren wenn bei Dateioperationen wie Reset Fehler auftreten (z.B. Datei existiert nicht). Mit {$I+} generiert er dann wieder Exceptions für Dateioperationen. Also deaktivieren wir das hier nur kurz für den Reset-Aufruf. Wir müssen dann aber selbst über IOResult prüfen, ob Reset erfolgreich war oder nicht. Bei Erfolg ist der Wert 0, und du kannst per Readln aus der Datei lesen. Bei Fehler wird deine GesH-Variable mit einem Standardwert initialisiert. Rewrite öffnet die Datei dann zur Ausgabe (ein vorheriges CloseFile ist nicht erforderlich) und löscht sie dabei komplett. Der try-finally Block hier sorgt dafür, dass CloseFile in jedem Fall aufgerufen wird, selbst wenn bei Readln, Rewrite oder Writeln Exceptions auftreten! Da du einen Integer (GesH) liest, würde Readln z.B. eine Exception erzeugen, wenn in der Datei kein Zahlenwert, sondern ein Buchstabe oder so drin steht. Wenn du diesen Fall behandeln möchtest, musst du auch um Readln einen {$I-}..{$I+} Block setzen und IOResult nach Readln prüfen... Aber warum sich plagen und mit diesen Uralt-Routinen Dateien lesen? Es kann durchaus Gründe dafür geben, z.B. wenn man das Programm so klein wie möglich halten will, keine VCL benutzt usw. Aber normalerweise geht es einfacher. Benutze TStream und seine Nachfahren (TStringStream), oder warum nicht INI-Dateien?
Delphi-Quellcode:
uses
IniFiles; var GesZ: Integer; procedure TForm1.Speichern; var Speicher: TIniFile; GesH: Integer; begin Speicher := TIniFile.Create('Speicher.txt'); try GesH := Speicher.ReadInteger('Variablen', 'GesH', 0); GesZ := GesH + GesZ; Speicher.WriteInteger('Variablen', 'GesH', GesZ ); finally Speicher.Free; end; end; |
AW: Textfiles Verständnisfrage & Frage
Zitat:
|
AW: Textfiles Verständnisfrage & Frage
@Perlsau, ja Grundlagenwissen ist immer guuuut (y) ;)
@SMO, erstmal vielen Dank, für die ausführliche Erklärung! :D Tjaa, warum sich plagen.. -.-'' Da wir nichts anderes gelernt haben in der Schule ;) Und wenn ich etwas nicht verstehe, nehme ich das, was ich verstehe :D siehe z.b.: ![]() |
AW: Textfiles Verständnisfrage & Frage
Zitat:
Am besten du machst es mit einer Stringliste, wobei du DateiName (String) selber festlegen mußt:
Delphi-Quellcode:
Procedure TForm1.Speichern;
Var Liste : TStringList; begin Liste := TStringList.Create; Try Liste.Append(Edit1.Text); Liste.SaveToFile(DateiName); Finally Liste.Free; End; end; |
AW: Textfiles Verständnisfrage & Frage
INI-Dateien sind reine Textdateien. Ursprünglich haben Windows-Programme sie benutzt, um INItialisierungswerte und Einstellungen zu speichern. Dann hat aber Microsoft die Entwickler dazu aufgefordert, solche Einstellungen stattdessen in der Registry zu speichern. Aber auch heute gibt es noch gute Gründe, INI-Dateien zu benutzen. Sie sind einfach editierbar und portabel (d.h. sie können zusammen mit dem Programm auf andere Rechner kopiert werden und die Einstellungen sind dort also auch sofort verfügbar).
Probier den Code doch einfach mal aus. Die erstellte Datei sollte damit so aussehen:
Code:
"Variablen" ist der Name des Abschnitts. Es kann mehrere Abschnitte in einer Datei geben, sie brauchen eindeutige Namen. "GesH" ist der Name des Schlüssels und "123" sein Wert.
[Variablen]
GesH=123 Viele Wege führen nach Rom. Aber nicht alle sind gleich gut bei einer gegebenen Problemstellung. Du solltest dir TStream und seine Nachfahren (TFileStream, TMemoryStream, TStringStream) wirklich anschauen, aber für deine Zwecke hier (eine Zahl in eine Datei speichern und wieder auslesen) könnte TIniFile (oder TMemIniFile) die komfortabelste Lösung sein. Denn damit wird das Konvertieren deines Integers in einen String und zurück automatisch übernommen. Und wenn die Datei nicht existiert oder der Wert kein Integer ist, dann wird keine Exception ausgelöst, sondern einfach der Standardwert benutzt (der letzte Parameter von TIniFile.ReadInteger). Mit einem Stream musst du dich selbst um solche Dinge kümmern. Du könntest natürlich auch den Binärwert des Integers in eine Datei schreiben (TFileStream.WriteBuffer), aber das wäre dann keine Textdatei mehr. |
AW: Textfiles Verständnisfrage & Frage
Sorry, SMO, aber wir haben's hier mit einem Schüler zu tun, der kaum das notwendigen Grundlagenwissen mitbringt, um deinen Ausführungen folgen zu können.
|
AW: Textfiles Verständnisfrage & Frage
Zitat:
In der Zwischenzeit darfst du erklären, wie Grayknife die GesH oder GesZ Integer aus dem ursprünglichen Programmschnipsel mit deinem Edit1.Text kombinieren kann. Aber bitte nicht überfordern! :cyclops: |
AW: Textfiles Verständnisfrage & Frage
@SMO achso, es sind trotzdem Dateien die mit .txt enden, aber "anders" gelesen werden da sie über andere Funktionen aufgerufen werden, hier mit ini&so. So wie es sich anhört sollte ich TiniFile ausprobieren, das hat dann nichts mehr mit ..Stream.. zu tun?
@Perlsau, Ja vielleicht verstehe ich nicht auf Anhieb alles, aber ich versuche es zu verstehen und umzusetzen. Und wenn ich nachfrage, ist das nicht der Faulheit halber, sondern eine Verständnisfrage! Denn meißtens ist es auf den Seiten so umständlich erklärt, dass man nicht EINE Sache versteht, obwohl man sich bemüht es zu verstehen. Und wenn man anfängt zu hinterfragen, warum ich genauer nachfrage und nicht selber google, dann würde all das hier sinnlos sein, alles was uns umgibt :roll: (denke ich mir jedenfalls) |
AW: Textfiles Verständnisfrage & Frage
Zitat:
Zitat:
Zitat:
Okay, nicht meine Ebene, ich blende mich hier aus. |
AW: Textfiles Verständnisfrage & Frage
Richtig, TIniFile hat nichts mit TStream zu tun. Deine ursprüngliche Herangehensweise mit AssignFile, Reset, Rewrite, Readln und Writeln funktioniert so schon seit über 30 Jahren, seit dem ursprünglichen Turbo Pascal, das Delphis Vorfahre war. Die hier vorgeschlagenen Lösungen mit TIniFile, TStream und auch TStringList sind alle "moderner" und basieren auf sogenannten Klassen/Objekten. Aber hier jetzt die Details objektorientierter Programmierung zu erörtern ginge in der Tat zu weit. Wenn du die alte Herangehensweise nicht benutzen musst, dann können Klassen bequemer sein.
Ini-Dateien haben gewöhnlich die Dateiendung .ini, also z.B. "Speicher.ini", aber es sind immer Textdateien, also ist es kein Problem auch .txt zu benutzen. Wie von mir angedeutet ist der Code von Perlsau unvollständig, würde aber prinzipiell auch funktionieren. Bei ihm fehlt das Lesen aus der Datei sowie die Typumwandlung von string nach Integer und umgekehrt. |
AW: Textfiles Verständnisfrage & Frage
Zitat:
Delphi-Quellcode:
Und wen ich mir jetzt noch die Meldung der Exception angucke, dass eine Datei nicht gefunden wurde, dann würde ich jetzt davon ausgehen, dass deine Anwendung die Datei im falschen Verzeichnis sucht und da natürlich nicht findet.
0procedure TForm4.btn1Click(Sender: TObject);
begin if OpenDialog1.Execute then Self.Caption := GetCurrentDir; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz