Externe Speicherung

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
kurev
Beiträge: 7
Registriert: Fr 7. Nov 2014, 23:37

Externe Speicherung

Beitrag von kurev »

Hallo, bin etwas neu im Umgang mit Lazarus und schreibe ein Quiz momentan.
Ich möchte die Spieler (name) und ihre erreichte Punktzahl (richtige Fragen) extern auf einer Datei speichern und dann in einer "Highscore" Prozedur eine Art Highscore Liste machen, wo Name des Spielers und seine Punktzahl stehen, sortiert nach richtigen Fragen.
Im Moment habe ich allerdings ein Problem beim Speichern/Aufrufen von Daten der Datei.
Hier sind meine Prozeduren zum Laden der Datei und Speichern der Datei und die "highscore Liste". Bei der Prozedur "laden" hab ich mich an einen Bsp im Informatikunterricht orientiert.
Wenn der Spieler im Quiz eine Frage richtig beantwortet, wird "spieler[anz].r" hochgezählt.

Meine Fragen sind jetzt, wie schaffe ich es, dass die Daten (Name und dazugehörige Punktzahl) in der Datei gespeichert werden und diese, geordnet, in der Prozedur Highscore ausgegeben werden ?
Danke im Vorraus
mfg Martin :)

Code: Alles auswählen

 
procedure laden;
var f: file of datei;
begin
assign(f,'C:\Highscore.DAT');
{$I-}
reset(f);
{$I+}
if ioresult <> 0 then
   begin
     writeln('Datei existiert nicht.');
     readln;
   end
   else
   begin
     read(f,spieler);
     while length (spieler[anz].name) <> 0 do
     inc(anz);
     close(f);
   end;
end
 


Code: Alles auswählen

procedure highscore;
var i:integer;
begin
     clrscr;
     writeln;
  for i:=1 to anz-1 do begin
    writeln(' Name : ',spieler[i].name, 'Richtige Fragen: ',spieler[i].r);
    writeln;
    readln;
  end;
end;   


Code: Alles auswählen

 
procedure speichern;
var f: file of datei;
begin
   assign(f,'C:\Highscore.DAT');
   rewrite(f);
   write(f,spieler);
   close(f);
end;     
 

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externe Speicherung

Beitrag von Mathias »

Am besten geht es, die Daten als Typeresierte-datei zu speichern. das geht in etwa so.

s währe in deinem Fall die Namen, Level die Punktzahl.

Code: Alles auswählen

type
  TSpielstand = record
    s:ShortString;
    Level, Leben, Munition: integer;
  end;
 
  TSpielstandArray=array[0..10] of TSpielstand;   


Speichern der Daten. Es hat 2 Varianten, einmal einzeln, oder als gesamtes Paket.

Code: Alles auswählen

procedure TForm1.saveClick(Sender: TObject);
var
  f: file of TSpielstand;
  farray: file of TSpielstandArray;
begin
  // Einzeln
 
  Spielstand.Level := StrToInt(Edit1.Text);
  Spielstand.s:=Edit2.Text;
  AssignFile(f, 'spielestand.dat');
  Rewrite(f);
  Write(f, Spielstand);
  CloseFile(f);
 
  // Die Array speichern
 
  Spielstand.Level := StrToInt(Edit1.Text);
  Spielstand.s:=Edit2.Text;
  AssignFile(farray, 'spielestandArray.dat');
  Rewrite(farray);
  Write(farray, SpielstandArray); // Hier kann man eine for Schleife einbauen
  CloseFile(farray);
end;


Laden eines Elemtes:

Code: Alles auswählen

procedure TForm1.loadClick(Sender: TObject);
var
  f: file of TSpielstand; // Dies gibt an, wie f aussieht.
begin
  AssignFile(f, 'spielestand.dat');
  Reset(f);
  Read(f, Spielstand); // Hier kann man eine for Schleife einbauen
  CloseFile(f);
  Edit1.Text := IntToStr(Spielstand.Level);
  Edit2.Text:=Spielstand.s;
end;


Code: Alles auswählen

spieler[i].name,
So wie ich es sehe, hast du schon einen Record und eine Array gemacht.

Ich hoffe mit meinem Beispiel kommst ein bischen weiter. :)
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

kurev
Beiträge: 7
Registriert: Fr 7. Nov 2014, 23:37

Re: Externe Speicherung

Beitrag von kurev »

:D danke für die Hilfe, aber ich mach das Programm nicht grafisch mit den Buttons usw., sondern einfach nur mit dem "Programmfenster", was den schwarzen Hintergrund hat und alles aus dem Programm angezeigt wird, weiß nicht wie ich das beschreibe

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externe Speicherung

Beitrag von Mathias »

aber ich mach das Programm nicht grafisch mit den Buttons usw.,

In dem Beispiel geht es nicht um Button, etc, es geht nur drum, wie man die Daten speichern kann. (Den Code zwischen begin und end;)
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

kurev
Beiträge: 7
Registriert: Fr 7. Nov 2014, 23:37

Re: Externe Speicherung

Beitrag von kurev »

Ich wollte aber allgemein wissen, was falsch an meinen Quelltext falsch ist und Befehle verwenden wie die, die ich verwendet habe und verstehe

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Externe Speicherung

Beitrag von wp_xyz »

Leider sagst du nicht, wie "spieler" genau deklariert ist. Es wird sich wahrscheinlich um ein Array handeln. Welche Elemente stecken in dem Array?

Deine "read"-Anweisung versucht das ganze Array auf 1x einzulesen. Woher weiß deine Routine denn, wie lang dein Array ist? Ich würde das Array Record für Record einlesen und aufhören, wenn das Datei-Ende (EoF) erreicht ist. Mit jedem Lesevorgang musst du im Array für die neuen Daten Platz schaffen (SetLength()).

Ich könnte dir ein fertiges Beispiel konstruieren, müsste dafür aber irgendwelche Annahmen machen. Poste erst mal die Deklaration deiner Datentypen.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Externe Speicherung

Beitrag von Michl »

Da Du hier wahrscheinlich sowieso einen fertigen Code bekommst...

Code: Alles auswählen

type
  TSpieler = Record
    name: ShortString;
    r: Integer;
  end;
 
var
  Spieler: Array of TSpieler;
 
procedure laden;
var f: file of TSpieler;
begin
assign(f,'C:\Highscore.DAT');
{$I-}
reset(f);
{$I+}
if ioresult <> 0 then
   begin
     writeln('Datei existiert nicht.');
     readln;
   end
   else
   begin
     SetLength(Spieler, 0);
     while not eof(f) do begin
       SetLength(Spieler, Length(Spieler) + 1);
       read(f, Spieler[High(Spieler)]);
     end;
     close(f);
   end;
end;
 
procedure HighScore;
var i:integer;
begin
  clrscr;
  writeln;
  for i:=Low(Spieler) to High(Spieler) do begin
    writeln(' Name : ',Spieler[i].name, 'Richtige Fragen: ',Spieler[i].r);
    writeln;
  end;
  readln;
end;
 
procedure Speichern;
var
  f: file of TSpieler;
  i: Integer;
begin
   assign(f,'C:\Highscore.DAT');
   rewrite(f);
   for i:=Low(Spieler) to High(Spieler) do
     write(f, Spieler[i]);
   close(f);
end;

PS: Heute setzt man eher AssignFile und CloseFile statt Assign und Close ein.
PS2: Die Variable "Name" im Record "Spieler" ist ebenfalls ungünstig gewählt, da "Name" schon als Property von TComponent gebräuchlich ist. Evtl. wirst Du später bei der objektorientierten Programmierungwirst noch darauf stoßen.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Antworten