Autor Beitrag
mithos
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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.


ausblenden volle Höhe Delphi-Quelltext
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;


   {
   procedure AssignFile(var F:file; Datei:string);
   begin
     AssignFile(F,Datei);
   end;

   procedure Rewrite(var F:file);
   begin
     Rewrite(F);
   end;

   procedure CloseFile(var F:file);
   begin
     CloseFile(F);
   end;
   }


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
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 107
Erhaltene Danke: 15

win 10

BeitragVerfasst: Mo 22.02.10 21:52 
Hallo mithos

Willkommen im Forum! :welcome:

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 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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:

ausblenden 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 = nilthen
       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
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 107
Erhaltene Danke: 15

win 10

BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mo 22.02.10 22:42 
ausblenden 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:
ausblenden Delphi-Quelltext
1:
2:
3:
// Write some numbers to the file as a single line
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 107
Erhaltene Danke: 15

win 10

BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  procedure preorder_rek(knoten : TKnoten);
  begin
     if not (knoten = nilthen
       begin
          WriteLn(F, knoten.inhalt);
          preorder_rek(knoten.links);
          preorder_rek(knoten.rechts);
       end;
  end;


in TKnoten habe ich inhalt als integer definiert

ausblenden 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
ausblenden Delphi-Quelltext
1:
Reset(F);					

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 107
Erhaltene Danke: 15

win 10

BeitragVerfasst: 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 23.02.10 00:41 
Moin!

user profile iconbole hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe gesehen Du hast eine rekursive Definition:

ausblenden 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. :idea: ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
mithos Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Di 23.02.10 10:20 
Oh, da war der Fehler also mit dem Write, vielen Dank :wink:


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.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1405
Erhaltene Danke: 51

Win 7, Android
Turbo Delphi, Eclipse
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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

ausblenden 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