Entwickler-Ecke

Dateizugriff - Array in Datei schreiben bzw danach auslesen


Simon - Fr 11.04.03 16:14
Titel: Array in Datei schreiben bzw danach auslesen
So.

Ich würde gerne ein Array in eine Datei schreiben. Bei der Suchfunktion habe ich zwar gefunden, wie man sie öffnet und schreiben/lesen kann, allerdings nie in einem Zusammenhang mit einem Array.

Das ganze soll für eine Highscore gut sein.

Also habe ich erstmal gemacht:


Quelltext
1:
datei2: file of highscore;                    



Quelltext
1:
2:
3:
4:
5:
type
    highscore = record
    name: string[30];
    versuche: integer;
  end;


So jetzt habe ich nicht mehr wirklich weitergewusst und habe mir einfach etwas zusammengereimt:


Quelltext
1:
2:
3:
4:
5:
6:
7:
assignfile(datei2,'highscore.dat');
     reset(datei2);
     while not eof(datei2) do
     begin
     platz := platz+1;
     read(datei2, highscore[platz]);
     end;


Anmerkung: In die Highscore sollen die 10 besten geschrieben werden. Ich weiß einfach nicht, was anstatt highscore[platz] da hinein soll. Es kommt die Fehlermeldung: [Fehler] Unit1.pas(257): '(' erwartet, aber '[' gefunden. So wenn ich was vergessen habe, sagts einfach ich trag es dann nach.

mfg, Simon


Klabautermann - Fr 11.04.03 16:52

Hallo,

zuerst einmal solltest auch du dein Record als Packed deklarieren:

Quelltext
1:
2:
3:
4:
5:
type
  highscore = packed record
  name: string[30];
  versuche: integer;
 end;

das erhört die Kompatibilität (wenn du dein Programm mal mit einer anderen Delphi version kompilierst und vermindert den Speicherverbraus (auch wenn das eigentlich vernachlässigt werden kann).

Dann musst du vor dem öffnen natürlich sicherstellen, dass die Datei Existiert.
Das einlesen selber würde ich so machen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
assignfile(datei2, ExtractFilePath(ParamStr(0)) + 'highscore.dat');
   reset(datei2); // hier währe eine Sicherheitsabfrage nicht schlecht, siehe IORESULT
   platz := 0
   while not (eof(datei2)) AND (platz<11)  do
   begin
   platz := platz+1;
   read(datei2, highscore[platz]);
   end;
  closeFile(Datei2);


Alles in allen war dein Code also richtig, ich habe eine Initialisierung, eine weitere Sicherheitsüberprüfung sowie das schließen der Datei hinzugefügt.
Wen die Datei also Existiert, dann müsste es vorher schon funktioniert haben, wenn nicht, damm must du sie erst spichern:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure WirteHighScore;
  var
    i : Byte;
begin
  rewrite(datei2); 
  FOR i := 1 TO 10 DO 
    Write(datei2, highscore[platz]);
  closeFile(Datei2);
end;


Gruß
Klabautermann


Simon - Fr 11.04.03 16:56

Es kommt schon wieder der Fehler. Er vermisst in der Zeile


Quelltext
1:
read(datei2, highscore[platz]);                    


irgendwie noch ein (, aber ich kann mir einfach nicht erklären warum.


Klabautermann - Fr 11.04.03 17:31

Entweder ich bin jetzt auch blockiert oder es ist etwas, das außerhalb des geposteten codes liegt.

Ich möchte dich mal bitten hier [http://downloads.oitmann.de/samples/] das TypeFile Demo runterzuladen und mit deinem Code zu vergleichen. Vieleicht findest du ja dadurch schon den Fehler. Wenn nicht könnest du deinen Programmcode hier zum Download anbieten oder ihn mit zumailen, dann gucke ich mal drüber.

Gruß
Klabautermann


Simon - Fr 11.04.03 18:44

Hab ihn mir mal deinen Link betrachtet, aber keinen Fehler gefunden. Allerdings hab ich bei dem Code auch nicht wirklich verstanden..

Klick mich ich bin ein Download [http://www.udh-clan.de/downloads/Memory.zip].


Klabautermann - Fr 11.04.03 20:08

Hallo,

also das Problem währe zu entdecken gewesen.

Also die Zeile
read(datei2, highscore[platz]);
kann nicht funktionieren, weil highscore keine Veariable (kein Array) sondern dein Datentyp ist:

Quelltext
1:
2:
3:
4:
5:
type
 highscore = packed record
 name: string[30];
 versuche: integer;
end;

Um solche verwechselungen zu vermeiden, solltest du dir angewöhnen alle DatenTypen mit dem Buchstaben T für Type beginnen zu lassen, wenn du dir Beispielprogramme ansiehst, wirst du merken, das die überwiegende anzahl aller Programmierer das so macht. Das währe dan also dieses konstrukt:

Quelltext
1:
2:
3:
4:
5:
type
 Thighscore = packed record
   name: string[30];
   versuche: integer;
  end;

Danach musst du bei deinen Globalen Variablen (je erfahrender du wirst, desto weniger wirst du die so verwenden ;)) noch einen entsprechendes Array deklarieren:

Quelltext
1:
2:
  VAR
    HighScore : ARRAY[1..10] OF THighscore;

und schon sollte das ganze klappen ;).

Gruß
Klabautermann


Simon - Fr 11.04.03 22:53

OK Dankeschön, aber das wusste ich halt nicht. Unser Informatiklehrer ist leider sehr inkompetent.. er kann zwar einiges, aber ist nicht wirklich in der Lage sein Wissen zu übermitteln. Also muss ich mir wohl oder übel alles selbst beibringen :).

Nun tritt ein komisches anderes Problem auf. Ich möchte ja in die Datei immer den Namen und die Versuche schreiben, die man gebraucht hat.


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:
procedure proc_gewonnen;
var i:byte;
platz:byte;
begin
   assignfile(datei2, ExtractFilePath(ParamStr(0)) + 'highscore.dat');
   reset(datei2); // hier währe eine Sicherheitsabfrage nicht schlecht, siehe IORESULT
   platz := 0;
   while not (eof(datei2)) AND (platz<11)  do
   begin
   platz := platz+1;
   read(datei2, highscore[platz]);
   end;
   i:=10;
   while versuche < highscore[i].versuche do
   begin
   highscore[i+1].name := highscore[i].name;
   highscore[i+1].versuche := highscore[i].versuche;
   highscore[i].name := 'Simon';
   highscore[i].versuche := versuche;
   i:=i-1;
   end;
   rewrite(datei2);
   FOR i := 1 TO 10 DO
   Write(datei2, highscore[i]);
   closeFile(Datei2);
   show_highscore;
end;


In der Variable versuche sind die benötigten Versuche enthalten (klar...) und den Namen habe ich halt erstmal nur Simon genannt um alles zu testen. Jetzt werde ich aber irgendwie so in die Highscore eingetragen: "1 '%% $$ !" 319557390" Eine komplizierte Anordnung von irgendwelchen willkürlichen Zeichen halt..

Ist mir irgendwie ein Rätsel. Setze ich versuche auf 35 und führe dann die procedure aus, so kommt das gleiche raus. Wenn ich am Anfang showmessage(floattostr(versuche)); mache, so zeigt er mir auch die korrekte Anzahl an. Ich habe keine Ahnung warum der das alles so komisch verdreht. Woran könnte es liegen??

mfg, Simon