Autor |
Beitrag |
mithos
Hält's aus hier
Beiträge: 6
|
Verfasst: Mo 22.02.10 20:38
Hallo
ich habe eine Frage dazu, wie ich einen Binärbaum, der Zahlen enthält, in eine Datei speichern kann.
Ja, es sind Hausaufgaben, allerdings brauche ich nur mal einen Stoß in die richtige Richtung. Das Wiederherstellen des Baumes ist auch Teil der Aufgabe, allerdings bin ich ehrlich gesagt schon froh, wenn ich das Speichern hinkriege.
Die eine Liste der Dateioperationen haben wir bekommen, allerdings weiß ich nicht, wie genau ich jene benutzen soll.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| procedure tBaum.toDatei; var F:file of integer; daten, datei : string;
begin AssignFile(F, Datei); Rewrite(F); daten := inorder; Readln(daten); WriteLn(F, daten);
CloseFile(F); end; |
Inorder ist eine Funktion, die als Rückgabewert einen String mit allen Knoten zurückgibt.
Der auskommentierte Teil war zuerst noch drin, das war mein 1. Versuch, die Dateioperationen anzuwenden :/
In welcher Form muss ich diese denn nun anweden? Reicht es, einfach nur
AssignFile(F, Datei);
anstatt
Delphi-Quelltext 1:
| procedure AssignFile(var F:file; Datei:string); |
anzugeben? Wenn nein, muss ich noch etwas in diese Prozedur reinschreiben?
Delphi selbst gibt jetzt als Fehlermeldung nur aus: [Pascal Fehler] mTBinBaum.pas(374): E2054 Ungültiger Typ in Write/Writeln-Anweisung
'daten' ist ja auch ein string, wohingegen das file vom Typ Integer sein soll. Ich habe aber keine Ahnung, wie ich Zahlen in die Datei schreiben soll. Über Google habe ich eben nur den write Befehl gefunden, der aber wohl nur für strings ist.
Bin für alle Tipps dankbar.
Gruß
|
|
bole
      
Beiträge: 107
Erhaltene Danke: 15
win 10
|
Verfasst: Mo 22.02.10 21:52
Hallo mithos
Willkommen im Forum!
Die Proceduren Assignfile, Closefile... die Du in Kommentar gesetzt hast kannst Du löschen, das sind Befehle.
Bei dem Befehl Assignfile musst Du als zweiten Parameter einen kompletten Dateinamen angeben. Komfortabler ist es mit dem TSaveDialog (siehe Hilfe / Suche im Forum)
Dein Problem beim speichern ist aber das Du zuviel auf einmal willst! Das speichern musst Du pro Knoten machen und nicht alle mitteinander. Ich nehme an deine Inorder Funktion besteht aus etwa 3 rekursiven aufrufen. Statt dir einen grossen String aus den Knoten zusammenzubasteln musst du sie jeweils auf in das File speichern.
Ich würde die Befehle der Funktion Inorder in die Speicherprocedure kopieren.
_________________ ein programm macht nicht das was du willst sondern was du schreibst!
|
|
mithos 
Hält's aus hier
Beiträge: 6
|
Verfasst: Mo 22.02.10 22:13
Hallo bole und danke für deine Antwort!
Ich habe deine Ratschläge versucht umzusetzen. Meine Prozedur sieht nun folgendermaßen aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure tBaum.toDatei; var F:file of integer;
procedure inorder_rek(knoten : TKnoten); begin if not (knoten = nil) then begin inorder_rek(knoten.links); WriteLn(F, knoten.inhalt); inorder_rek(knoten.rechts); end; end;
begin AssignFile(F, 'Desktop:\binBaumSaveLoad.txt'); Rewrite(F);
inorder_rek(wurzel);
CloseFile(F); end; |
Wenn ich versuche, zu compilieren, erscheint die folgende Fehlermeldung: [Pascal Fehler] mTBinBaum.pas(355): E2054 Ungültiger Typ in Write/Writeln-Anweisung zu der Zeile
Delphi-Quelltext 1:
| WriteLn(F, knoten.inhalt); |
Kommt die Fehlermeldung daher, dass ich nur strings mit Writeln schreiben kann? Wie kann ich sonst Zahlen in eine Datei schreiben, gibt es dafür einen anderen Befehl?
Vielen Dank schon mal bis hierhin.
Gruß
|
|
bole
      
Beiträge: 107
Erhaltene Danke: 15
win 10
|
Verfasst: Mo 22.02.10 22:23
Du hast eine Idee zur Lösung... hast Du die probiert?
Interessant wäre wie Du TKnoten definiert hast, ist Knoten.inhalt vom Typ Integer?
Du schreibst auch im Assignfile ein File mit der Endung .txt; Für Delphi ist das kein Problem aber mit den Notepad kann man dieses nicht wirklich lesen...
GRuss
Bole
_________________ ein programm macht nicht das was du willst sondern was du schreibst!
|
|
mithos 
Hält's aus hier
Beiträge: 6
|
Verfasst: Mo 22.02.10 22:42
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| TInhalt = integer;
TKnoten = class private inhalt: TInhalt; links,rechts: TKnoten; constructor create(inhalt : TInhalt); public function gibLinks : tKnoten; function gibRechts : tKnoten; function gibInhalt : TInhalt; end; |
Also ja, inhalt ist vom Typ integer.
Ich habe eben gerade etwas per Google gefunden bezüglich des write Befehls, allerdings hilft mir das nicht weiter:
Delphi-Quelltext 1: 2: 3:
| for i := 2 to 4 do Write(myFile, i/2, ' '); |
hier scheint das ja zu klappen, mit dem write Befehl auch Zahlen zu schreiben, wieso klappt das bei mir nicht? *ratlos*
Noch eine Frage zum zweiten Aufgabenteil, in dem gefordert ist, die integer Werte auch wieder aus der Datei zu lesen und in den Baum einzufügen.
Das Problem ist, dass ich nicht einfach die Werte nacheinander lesen und wieder einfügen kann, da dies zu einem Baum führen würde, der zu einer Liste entartet ist, da ich ja inorder eingelesen habe. Theoretisch kann ich aber einfach preorder die Knoten lesen und in die Datei schreiben. Dadurch kann ich dann auch einfach die Werte nacheinander lesen und wieder einfügen und ich erhalte den selben Baum, richtig?
|
|
bole
      
Beiträge: 107
Erhaltene Danke: 15
win 10
|
Verfasst: Mo 22.02.10 22:59
Der Variable knoten.inhalt ist nicht vom Typ integer sondern vom Typ TInhalt. TInhalt macht meines erachtens nicht viel Sinn, es ist ja einfach ein integer. Definiere inhalt als integer statt als TInhalt.
_________________ ein programm macht nicht das was du willst sondern was du schreibst!
|
|
mithos 
Hält's aus hier
Beiträge: 6
|
Verfasst: Mo 22.02.10 23:17
Habe TInhalt rausgenommen, und es überall durch integer ersetzt, kriege aber immernoch die selbe Fehlermeldung..
Habe inorder zu preorder verändert, der Prozedurteil sieht nun so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure preorder_rek(knoten : TKnoten); begin if not (knoten = nil) then begin WriteLn(F, knoten.inhalt); preorder_rek(knoten.links); preorder_rek(knoten.rechts); end; end; |
in TKnoten habe ich inhalt als integer definiert
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| TKnoten = class private inhalt: integer; links,rechts: TKnoten; constructor create(inhalt : integer); public function gibLinks : tKnoten; function gibRechts : tKnoten; function gibInhalt : integer; end; |
Fehlermeldungen
[Pascal Fehler] mTBinBaum.pas(354): E2054 Ungültiger Typ in Write/Writeln-Anweisung und
[Pascal Fehler] mTBinBaum.pas(354): E2008 Inkompatible Typen
Weiterhin erhalte ich bei
Delphi-Quelltext
ain meiner anderen Prozedur zum Schreiben in den Baum die Fehlermeldung [Pascal Fehler] mTBinBaum.pas(378): E2034 Zu viele Parameter.
Reicht es denn, in der anderen Prozedur nur Reset(F); aufzurufen? AssignFile wird ja nur einmal benötigt und das habe ich ja in der anderen Prozedur..?
Danke
Gruß
|
|
bole
      
Beiträge: 107
Erhaltene Danke: 15
win 10
|
Verfasst: Di 23.02.10 00:14
Hast Du mal die Hilfe von Writeln gelesen?
'WriteLn ist eine Erweiterung der Prozedur Write , die für Textdateien definiert ist.'
Writeln funktioniert nicht nimm Write!
Kleine Frage am Rande: Dein Binärer Baum funktioniert mit Bildschirmausgaben (z.B. in Memo Feld?) Wenn nicht, ist das der erste Schritt den es zu korrigieren gibt.
Ich habe gesehen Du hast eine rekursive Definition:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| TKnoten = class private inhalt: integer; links,rechts: TKnoten; constructor create(inhalt : integer); public |
Ob dies geht oder nicht würde micht interessieren, ich kommen von der strukturierten Programierung, da hat man classen sondern Records und Pointer definiert... Ich nehme an links und rechts sollten auch eher Pointer auf TKnoten sein.
Poste doch mal Dein ganzes Projekt, aber leider komme ich heute und wahrscheinlich morgen nicht dazu das anzuschauen. Aber vielleicht findet sich ja jemand anders der Dir schneller Hilft
gruss
bole
_________________ ein programm macht nicht das was du willst sondern was du schreibst!
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 23.02.10 00:41
Moin!
bole hat folgendes geschrieben : | Ich habe gesehen Du hast eine rekursive Definition:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| TKnoten = class private inhalt: integer; links,rechts: TKnoten; constructor create(inhalt : integer); public |
Ob dies geht oder nicht würde micht interessieren, ich kommen von der strukturierten Programierung, da hat man classen sondern Records und Pointer definiert... Ich nehme an links und rechts sollten auch eher Pointer auf TKnoten sein. |
Das ist schon OK so, Klassenreferenzen sind sowieso Pointer, aber eben typisierte.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
mithos 
Hält's aus hier
Beiträge: 6
|
Verfasst: Di 23.02.10 10:20
Oh, da war der Fehler also mit dem Write, vielen Dank
Das Programm liest eine Eingabe aus einem Feld in den Baum, welchen es auch graphisch darstellt.
Soweit ist alles gelöst, das einzige, was immer noch nicht geht, ist das Reset(F), da gibt er mir immer [Pascal Fehler] mTBinBaum.pas(378): E2034 Zu viele Parameter
als Fehlermeldung.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure tBaum.fromDatei; var F:file of integer; KnInhalt: integer;
begin
Reset(F); while not eof(F) do begin Read(F, KnInhalt); FuegeEin(KnInhalt); end;
CloseFile(F); end; |
Danke und schönen Gruß
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: Di 23.02.10 20:00
Also das Reset(F) sollte korrekt sein, aber du musst davor noch mit AssignFile die Datei öffnen.
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
mithos 
Hält's aus hier
Beiträge: 6
|
Verfasst: Di 23.02.10 21:05
Ich erhalte immer noch die selbe Fehlermeldung, auch wenn ich das Assignfile nochmal reinnehme.
Da werd ich wohl meinen Informatiklehrer in der nächsten Stunde mal zu Rate ziehen müssen.
Wenn noch jemand eine Idee hat, warum diese Fehlermeldung auftritt, kann er sich ja nochmal hier melden, ansonsten hab ich die Hilfe, die ich gesucht habe, bekommen.
Vielen Dank
Gruß
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mi 24.02.10 09:23
Hallo,
ich hatte früher eher Ärger mit EOF(F).
Ein File of DatenTyp hat aber den Vorteil, dass man, im Gegesatz zu Textdateien, die Größe abfragen kann.
www.delphibasics.co....Unit.asp?Unit=System und dort www.delphibasics.co....TL.asp?Name=FileSize
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure tBaum.fromDatei; var F:file of integer; KnInhalt: integer; i : integer; begin AssignFile(F, 'Desktop:\binBaumSaveLoad.txt'); Reset(F); For i := 1 to fileSize(F) do begin Read(F, KnInhalt); FuegeEin(KnInhalt); end;
CloseFile(F); end; |
Gruß Horst
P.S.
O.K Bei Textdateien und untypisierten Dateien wird mit einer Größe von Datentyp von 128 Byte gerechnet
www.delphibasics.co.uk/RTL.asp?Name=Reset ausser man benutzt Reset mit dem Zusatz der Datentypgröße bei untypisierten Dateien
|
|
|