![]() |
ReadLn und WriteLn
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo
ich sitze (immer noch) an einem 3D-Viewer. Dazu habe ich eine Klasse "TModel" erstellt, die ihre eigenen Punkte in Vektorform speichert und selbst laden kann. Ich schreibe diese Punkte in eine Textdatei (Typ Textfile) und benutze den Befehl WriteLn. Beispiel:
Delphi-Quellcode:
Auslesen realisiere ich dann über ReadLn mit einer praktisch identischen Prozedur.
var f: Textfile;x,y,z: real;
begin WriteLn(f,x,y,z); end; Das Problem ist, dass ReadLn Leerzeichen zwischen den Werten fordert, WriteLn aber keine setzt. Ich kann das Problem zwar umgehen, indem ich folgende Zeile zum speichern benutze:
Delphi-Quellcode:
das finde ich aber nicht gerade schön.
WriteLn(f,x,' ',y,' ',z)
Mich interessiert jetzt bloß, warum diese beiden Prozeduren sich nicht genau gegenseitig ergänzen. |
Re: ReadLn und WriteLn
Warum schreibst du nicht einfach eigene Prozeduren/Funktionen dafür?
|
Re: ReadLn und WriteLn
Hmm, du schreibst mit IntToStr Koordinaten in eine Textdatei und liest sie dann mit StrToInt wieder aus? Warum dieses ganze TypeCasting? Wäre ein Record, z.B. TCoordinates mit einem entsprechenden File Of, also z.B. var f: File Of TCoordinates, nicht schneller? Dann hättest du auch keine Probleme mit Leer- oder sonstigen Sonderzeichen.
|
Re: ReadLn und WriteLn
mmh, ich hab das so einfach gelassen, damit ich leicht per Hand Modelle in eine Textdatei schreiben kann.
und in einer eigenen Prozedur stets doch... |
Re: ReadLn und WriteLn
Na dann kannst du das doch ohne Probleme so anpassen.
|
Re: ReadLn und WriteLn
danke erst mal für die Hilfe. Mir gind es bei dieser Frage bloß mehr um das Verständnis des Problems und nicht um die Lösung! Wie schon oben erwähnt, hab ich das Problem bereits gelöst.
Also wenn mir einer erklären kann, warum das mit den Leerzeichen so ist, dann bitte posten! mfg Paul |
Re: ReadLn und WriteLn
Zitat:
ich würde dir echt dazu raten die Tipps zu beherzigen, die dir hier gegeben wurden. Es ist mit anderen Lösungen für dich möglich die Daten sowohl komfortabel per hand zu bearbeiten als auch einfach (und fehlerfrei) im Programm die Daten einzulesen. Zu deinem eigentlichen Problem solltest du dir einfach nur anschauen, was du verwendest. Du hast eine Textdatei, alles was hier drin steht sind einfache Zeichenketten. Genauso wird Delphi diese auch interpretieren, ob eine Datei nun ein Wort oder 10 oder 100 enthält, für Delphi besteht die Datei aus einem langen String. Anhand der Leerzeichen (nur ein spezielles Zeichen im String) kann man hier trennen, man könnte aber auch ein Komma nehmen oder ein 'F' oder oder oder. Letztlich passiert immer das gleiche, man sucht im String nach einem Zeichen und teilt hier die Zeichenkette auf. Wenn du nur Werte in die Datei schreibst, dann weiß Delphi nicht dass es sich für dich dabei um getrennte Integer Werte handelt, für Delphi sind das einfache Strings und die können aneinander gehängt werden. Endet ein String mit dem Zeilenumbruch (oder startet einer damit) würde es für dich im Editor wie eine neue Zeile aussehen, für Delphi ist das weiterhin ein String, der halt an dieser Stelle ein besonderes Zeichen besitzt an dem man trennen kann. Das Textfile besitzt hier (um flexibel zu bleiben) keine eigenen Logik. Du kannst daraus eine CSV Datei bauen in dem du zwischen den Variablen einfach ein Trennzeichen einfügst, du kannst aber auch mehrere Zeilen übergeben (die mit einem Zeilenumbruch enden) und da brauchst du jeweils kein Leerzeichen zwischen zwei Einträgen. Dass du es jetzt für deine Integer möchtest, das weiß Delphi nicht. Du lädst irgendeine Textdatei und da steht nun mal nur irgendein Text drin. Sauberer ist es deswegen (und weil File nicht mehr aktuell ist) auf eine andere Implementierung zu setzen, z.B. könntest du alle Werte an eine TStringList übergeben, einen Delimiter verwenden und den hier generierten Text direkt speichern und auch wieder laden. Das zerlegen der Werte (und/oder einfügen von Trennzeichen) übernimmt dann schon die TStringList für dich. Natürlich wären auch die anderen schon genannten Lösungen besser als deine jetzige (sorry, aber ist so) |
Re: ReadLn und WriteLn
Hallo Paul,
der Schein trügt - ReadLn() verlangt keine Leerzeichen per se. Wenn du die Koordinaten (10,11,12) mit Write(x,y,z) wegschreibst, dann könntest du das gleiche Ergebnis auch mit Write(1,0,1,1,1,2) oder Write(101112) erzeugen. Jedes Argument der Prozedur wird in eine textuelle Darstellung überführt und weggeschrieben. Wer außer dir könnte sagen, wo ein Trenner gebraucht wird? Die Prozedure ReadLn() wäre auch mit jedem anderen Zeichen zufrieden, welches das Ende einer "Zahl" signalisieren kann. Leerzeichen sind aber besonders praktisch, da die Prozedur ReadLn() so implementiert ist, dass sie eine beliebige Anzahl an Leerzeichen überspringt um die nächste Zahl einzulesen. Auf diesen Komfort wollte und konnte man in der Anfangszeit von Pascal nicht verzichten - immerhin musste man gegen FORTRAN anstinken. Auf der Seite von WriteLn() ist die automatische Erzeugung von Ausgabezeichen keine so gute Idee, was unmittelbar einleuchten sollte. Es wäre ja sonst nie möglich gewesen eine Datei exakt nach dem Willen des Entwicklers zu erzeugen - immerhin waren früher Write() und WriteLn() die einzigen verfügbaren Ausgabe-Prozeduren. Die Standardprozeduren Read() / ReadLn() und Write() / WriteLn() fallen in Pascal wegen der variablen Parameterzahl sowieso etwas aus der Rolle. Bald werden sie ganz verschwunden sein. Freundliche Grüße |
Re: ReadLn und WriteLn
vielen dank für die ausführlichen Antworten, damit kann ich was anfangen.
Ich kann auch damit leben, dass meine Prozeduren schlecht sind. Immerhin bin ich ja hier um was zu lernen und nicht um zu beweisen wie "toll" ich programmieren kann! Also danke noch mal genau so hab ich mir die Antwort vorgestellt, bis zu meinem nächsten Problem :thumb: mfg Paul |
Re: ReadLn und WriteLn
Zitat:
Gruß Der Unwissende |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:08 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