Entwickler-Ecke

Dateizugriff - record abspeichern


furious - Di 07.10.03 18:00
Titel: record abspeichern
Hi,

also ich schildere mal mein Problem:

Ich möchte ein record in einer *.txt Datei speichern und mit einem index versehen, um es später wieder zu finden. es sollen also immer mehr records in diese textdatei geschrieben werden, die dann aber später wieder getrennt aufgerufen werden können und die man dann auch sortieren könnte.
ich hoffe ich habe mich verständlich ausgedrückt...


Anonymous - Di 07.10.03 18:04

muss es unbedingt eine textdatei sein?
sonst würde ich dir typisierte Dateien empfehlen.

z.B:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
type
 TTest = record
     a: integer;
     b: string[10];
 end;

...

var
 x: file of TTest;
 f: TTest;
begin
 assignfile(x, 'test.dat');
 rewrite(x);
 write(x,f);
 closefile(x);
end;


ansonsten hängt es von dem Record ab[/delphi]


furious - Di 07.10.03 18:17

Ok und wie lese ich das Record wieder aus?


Anonymous - Di 07.10.03 18:18

so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var 
 x: file of TTest; 
 f: TTest; 
begin 
 assignfile(x, 'test.dat'); 
 reset(x); 
 read(x,f); 
 closefile(x); 
end;


furious - Di 07.10.03 18:26

OK :D

und wie kann ich mir die am besten übersichtlich anzeigen lassen?? memo?

Vielen Dank schonmal für die hilfe!


Anonymous - Di 07.10.03 18:39

du kannst sie so alles auslesen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var 
 x: file of TTest;
 saetze: array of TTest
begin
 asssignfile(x, 'test.dat');
 reset(x);
 while not eof(x) do
 begin
  setlength(saetze, length(saetze)+1);
  read(x,saetze[high(saetze)]);
 end;
end;

(nicht getestet)

das darstellen hängt wieder vom Inhalt ab.[/delphi]


furious - Di 07.10.03 19:36

Also mein Record sieht so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
type
  TDatensatz = RECORD
  Index: integer;
  Lehrer: String[3];
  Spruch: String[255];
end;


wobei ich mir noch nicht sicher bin, wie ich mit dem index umgehe, ob ich ihn brauche,...?!


Anonymous - Di 07.10.03 20:32

wenn du ein Array hast, kannst du auf index Verzichten.
Mit diesem Datensatz müsste es aber so funktionieren wie ich gesagt habe.


furious - Di 07.10.03 20:37

obbschtkuche hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var 
 x: file of TTest;
 saetze: array of TTest
begin
 asssignfile(x, 'test.dat');
 reset(x);
 while not eof(x) do
 begin
  setlength(saetze, length(saetze)+1);
  read(x,saetze[high(saetze)]);
 end;
end;



Scheint prinzipiell zu funktionieren. (Kein Compiler-Fehler)

Aber wie kann ich mir das array wieder ausgeben lassen? Also so, dass ich jeden datensatz sehe? oder kann ich nur mit array[x] nen bestimmten DAtensatz anzeigen lassen?


Anonymous - Di 07.10.03 20:44

ich hab noch was wichtiges vergessen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
var  
 x: file of TTest; 
 saetze: array of TTest 
begin 
 asssignfile(x, 'test.dat'); 
 reset(x); 
 setlength(saetze,0);
 while not eof(x) do 
 begin 
  setlength(saetze, length(saetze)+1); 
  read(x,saetze[high(saetze)]); 
 end; 
end;


danach kannst du die z.B. so anzeigen lassen:


Delphi-Quelltext
1:
2:
for i := 0 to high(saetze) do
 memo1.lines.add(saetze[i].name + ': ' + saetze[i].blubb);
[/delphi]


furious - Di 07.10.03 20:57

Hm...

aber wie schreibe ich mein record ins array ohne dabei das vorhergehende zu überschreiben, so dass mein array immer größer wird?


Anonymous - Di 07.10.03 20:59

so:

Delphi-Quelltext
1:
2:
  setlength(saetze, length(saetze)+1);  
  read(x,saetze[high(saetze)]);



Delphi-Quelltext
1:
  setlength(saetze, length(saetze)+1);                    


verlängert das Array um 1


Delphi-Quelltext
1:
saetze[high(saetze)]                    


liefert das letzte Element zurück


furious - Mi 08.10.03 11:49

Hi, also irgendwie komme ich nicht weiter...

ich poste mal meinen ganzen quelltext und nen screen von meiner oberfläche, vielleicht verstehst du ja wo mein problem liegt.... Ich habs irgendwie net drauf. Probier schon seit 2 Stunden rum.

Wie ich die Sprüche dann in ner Liste ausgebe bin ich mir auch noch nicht sicher, also ob ne strukturierte Textdatei oder wieder ein Memo...


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:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
//-----------------------------------
// RECORD erstellen in welchem Lehrer und Spruch festgehalten werden
//-----------------

type
  TSpruch = RECORD
  Lehrer: String[3];
  Text: String[255];
end;

//-----------------------------------
//  Den Pfad angeben in welchem die Datei sprueche.dat zu finden ist
//-----------------

const
  pfad='c:\windows\desktop\projekt_delphi\sprueche.dat';

//-----------------------------------
//  Globale Variablen deklarieren
//-----------------

var
  Form1: TForm1;
  f: file of TSpruch;          // für die sprueche.dat
  datensatz: array of TSpruch; //  Array "Datensatz" für die records "Spruch"
  Spruch: TSpruch;             // Record für Variable "Spruch" verwenden


// =================(-)=================


implementation

{$R *.DFM}


//-----------------------------------
//  Spruch hinzufügen
//------------------

procedure TForm1.BTNaddClick(Sender: TObject);
begin
  Datensatz.spruch.Lehrer:=CBBlehreradd.text;  // Hier krieg ich die Fehlermeldung:
  Datensatz.spruch.text:=MMSpruch.text;       // "Record, Objekt oder Klassentyp erforderlich"


              // ???????????????
end;


//-----------------------------------
//  Auslesen der sprueche.dat
//------------------

procedure TForm1.BTNshowallClick(Sender: TObject);
var i,h:integer;
begin
 assignfile(f, pfad);
 reset(f);
 setlength(datensatz,0);
 while not eof(f) do
 begin
  setlength(datensatz, length(datensatz)+1);
  read(f,datensatz[high(datensatz)]);
 end;
 h:=high(datensatz);
 for i := 0 to h do
 MMspruch.lines.add(datensatz[i].lehrer + ': ' + datensatz[i].text);
end;

end.


user defined image


Klabautermann - Mi 08.10.03 12:03

Hallo,

ich muss zugeben, das ich den Thread nciht gelesen habe aber ich wollte trotzdem anmerken, das du deinen Record als packed definieren solltest. Dadurch wird 1. Die Datei kleiner und 2. gibt es keine Inkompatibilitäten wenn mal eine Kompilat deines Programms, auf einer Delphi Version mit anderen Grundeinstellungen erzeugt wird. Das ganze würde dann so aussehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
type
  TSpruch = packed RECORD
  Lehrer: String[3];
  Text: String[255];
end;


Übrigens kannst du dir hier [http://downloads.oitmann.de/samples] ein einfach Beispiel zu Typisierten Dateien runterladen (Type-File Demo).

// Edit: Oh und noch etwas:
das hier:

Delphi-Quelltext
1:
2:
3:
4:
setlength(datensatz,0); 
 while not eof(f) do 
 begin 
  setlength(datensatz, length(datensatz)+1);

solltest du nicht machen. Durch einen Bug im Speichermanagement von Delphi [http://www.delphi-forum.de/viewtopic.php?p=44621#44621] kommt es beim Vergrößern deines Arrays zu Speicherverlusten (speicherleichen) deshalb solltest du so selten wie möglich die Größe ändern. In diesem Fall also nur ein mal vor der Schleife.

Gruß
Klabautermann


furious - Mi 08.10.03 19:37

Danke, die TypeFileDemo ist sehr hilfreich...

aber wie sieht es hiermit aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.BTNaddClick(Sender: TObject); 
begin 
  Datensatz.spruch.Lehrer:=CBBlehreradd.text;  // Hier krieg ich die Fehlermeldung: 
  Datensatz.spruch.text:=MMSpruch.text;       // "Record, Objekt oder Klassentyp erforderlich" 


              // ??????????????? 
end;


Der Array macht mir irgendwie Probleme...


Anonymous - Mi 08.10.03 19:40

mach es so:

MMSpruch[index (eine nummer)].text


furious - Mi 08.10.03 19:43

MMSpruch ist das Memo... CBBlehrer ne ComboBox...

das Array ist datensatz... spruch ist das record...


Anonymous - Mi 08.10.03 19:50

dann Spruch[index]


furious - Mi 08.10.03 19:52

...gleiche Fehlermeldung... auch wenn ich datensatz nen index gebe oder beiden....


Anonymous - Mi 08.10.03 19:54

jetzt hab ich mir mal angesehen was überhaupt das array ist. also musst du datensatz und nicht spruch einen index geben.


furious - Mi 08.10.03 19:59

furious hat folgendes geschrieben:
...gleiche Fehlermeldung... auch wenn ich datensatz nen index gebe oder beiden....


Anonymous - Mi 08.10.03 20:00

Argghhhh... sprung ist string, also musst du datensatz einen index geben und das .text weglassen.


furious - Mi 08.10.03 20:08

Sorry, aber wenn du sowas meinst:

Delphi-Quelltext
1:
Datensatz[1].spruch.text:=MMSpruch                    

geht nicht....


Anonymous - Mi 08.10.03 20:09

das .text weglassen, also


Delphi-Quelltext
1:
Datensatz[1].spruch:=MMSpruch.text;                    


oder wasauchimmer...[/delphi]


furious - Mi 08.10.03 20:13

Ich glaub wir kommen so nicht weiter...

hättest du, oder jemand anderes vielleicht die güte sich meine oberfläche anzusehen:
user defined image
Die Anforderungen an mein Programm ergeben sich ja so automatisch.

Wie setze ich das am besten um?