Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Textdatei sortieren (https://www.delphipraxis.net/64631-textdatei-sortieren.html)

boozzz 6. Mär 2006 13:37


Textdatei sortieren
 
Hi zusammen,
mein Quellcode soll verschiedene Werte einer Textdatei einlesen und sortieren. Die sortierten Werte sollen in einer Highscore-Liste angezeigt werden.

In der Textdatei stehen abwechselnd Wert und Benutzer in einer Zeile. Beispiel: In der ersten Zeile steht die Punktzahl von Benutzer 1. Der Name von Benutzer 1 seht in der zweiten Zeile. In der dritten Zeile steht die Punktzahl von Benutzer 2. Der Name von Benutzer 2 seht in der vierten Zeile, usw.

Das Problem: Es werden nur die ersten 10 Werte in der Textdatei sortiert. Der 11. Benutzer wird nicht mehr in der Sortierung berücksichtigt. :pale:

Würde mich freuen, wenn sich das jemand mal anschauen könnte, DANKE.

Delphi-Quellcode:
procedure TForm1.bestenlistebuttonClick(Sender: TObject);    
var ende,zwischenspeicher,lauefer,lauefer2,x,y,wertespeicher,wabbel:integer;    
    personenspeicher: string;    
    platz: array[1..100] of integer;    
    person: array[1..100] of string;    
begin    
  bestenliste.Show;    

  highscore:=TStringList.Create;    
  if FileExists ('memory.txt') then    
  begin    
    highscore.LoadFromFile('memory.txt');    
    ende:=highscore.Count;    

    lauefer:=0;    
    lauefer2:=1;    

    for x:=1 to 10 do    
    begin    
      if (highscore.Count/2>=x) then    
      begin    
        platz[x]:=StrToInt(highscore[lauefer]);    
        lauefer:=lauefer+2;    
        person[x]:=highscore[lauefer2];    
        lauefer2:=lauefer2+2;    
      end;    
    end;    

    for y:=1 to 10 do    
    begin    
      for x:=1 to 10 do    
      begin    
        if (highscore.Count/2>=x) then    
        begin    
          if platz[x+1]<platz[x] then    
          begin    
            wertespeicher:=platz[x];    
            personenspeicher:=person[x];    
            platz[x]:=platz[x+1];    
            person[x]:=person[x+1];    
            platz[x+1]:=wertespeicher;    
            person[x+1]:=personenspeicher;    
          end;    
        end;    
      end;    
    end;    

    bestenliste.Label1.Caption:=IntToStr(platz[2]);      //hier folgt die Ausgabe in die einzelnen Labels
    bestenliste.Label2.Caption:=IntToStr(platz[3]);    
    bestenliste.Label3.Caption:=IntToStr(platz[4]);    
    bestenliste.Label4.Caption:=IntToStr(platz[5]);    
    bestenliste.Label5.Caption:=IntToStr(platz[6]);    
    bestenliste.Label6.Caption:=IntToStr(platz[7]);    
    bestenliste.Label7.Caption:=IntToStr(platz[8]);    
    bestenliste.Label8.Caption:=IntToStr(platz[9]);    
    bestenliste.Label9.Caption:=IntToStr(platz[10]);    

    bestenliste.Label39.Caption:=person[2];    
    bestenliste.Label38.Caption:=person[3];    
    bestenliste.Label37.Caption:=person[4];    
    bestenliste.Label36.Caption:=person[5];    
    bestenliste.Label35.Caption:=person[6];    
    bestenliste.Label34.Caption:=person[7];    
    bestenliste.Label33.Caption:=person[8];    
    bestenliste.Label32.Caption:=person[9];    
    bestenliste.Label31.Caption:=person[10];    

    highscore.Free;    
  end;    
end;

Klaus01 6. Mär 2006 13:47

Re: Textdatei sortieren
 
hallo,

um es etwas einfacher zu machen:

Warum bastelst DU die nicht aus der Stringlist
wo in [i] die Punkte stehen und in [i+] der Teilnehmer
eine Stringlist wi in [i] die Punkte und der Teilnehmer stehen.

Diese Stringlist ließe sich mit stringlist.sort sortieren
und Du müsstest nur die ersten 10 "Zeilen" [0-..9] ausgeben umd die
ersten 10 Teilnehmer zu erhalten.

Grüße
Klaus

Angel4585 6. Mär 2006 13:50

Re: Textdatei sortieren
 
Zitat:

Zitat von Klaus01
hallo,
Diese Stringlist ließe sich mit stringlist.sort sortieren
und Du müsstest nur die ersten 10 "Zeilen" [0-..9] ausgeben umd die
ersten 10 Teilnehmer zu erhalten.

bei Stringlist.sort würde aber die Reihenfolge u.U. so aussehen:

1
10
2
3
4
5
6
7
8
9

wenn ich mich nicht täusche.

Klaus01 6. Mär 2006 13:53

Re: Textdatei sortieren
 
ups,

wie schaut es denn aus, wenn Anzahl der Stellen
vor dem Zusammenfügen der Zeilen [i] und [i+1]
angeglichen werden.

So das aus 1 z.b. 01 usw. wird.

Grüße
Klaus

Angel4585 6. Mär 2006 13:57

Re: Textdatei sortieren
 
@boozz:

Also ich würde ganz spontan mal vorschlagen, die Schleifen nicht nur bis 10 laufen zu lassen, sondern bis 100.

Ausserdem würd ich das ganze mit records machen:

Delphi-Quellcode:
type
TScore = record
 person : string[100];
 Punkte : Integer;
 end;
machst du einmal ein:

Delphi-Quellcode:
highscore :array of TScore;
und speicherst das mit:

Delphi-Quellcode:
var
 f : file of TScore;
 i : integer;
begin
AssignFile(f,'Dateiname');
rewrite(f);
for i:= 0 to Pred(Length(highscore)) do
 write(f,highscore[i]);
CloseFile(f);
end;
und laden kannst das mit:

Delphi-Quellcode:
var
 f : file of TScore;
begin
SetLength(highscore,0);
AssignFile(f,'Dateiname');
reset(f);
while not eof(f) do
 begin
 SetLength(highscore,Succ(Length(highscore)));
 read(f,highscore[Pred(Length(Highscore))]);
 end;
CloseFile(f);
end;
Ungetestet, sollte aber funktionieren

Edit: ach du Sch... wie iss denn das eingerückt?? :gruebel: :oops: :twisted: Mach mal jemand was.. sieht ja furchtbar aus!

boozzz 11. Mär 2006 13:07

Re: Textdatei sortieren
 
Hallo nochmal,
an den Schleifendurchläufen (Schleife läuft bis 10) liegt es nicht. Wenn ich die Schleifen bis 100 laufen lasse, werden die Werte nicht richtig sortiert. Die Schleife ist nur dazu da, um bei weniger als 10 Einträgen eine Fehlermeldung auszuschließen.

Die Möglichkeit mit den Records hab ich als Delphi-Neuling nicht ganz verstanden. :wiejetzt:

Aber das müsste doch theoretisch auch so gehen, wie ichs versucht habe, oder? Die ersten 10 Einträge werden bei mir nämlich problemlos sortiert.

Würde mich freuen, wenn jemand in meinem Code einen Fehler findet,

Grüße,

boozzz

Klaus01 11. Mär 2006 14:32

Re: Textdatei sortieren
 
vielleicht kannst Du deinen Code mal etwas kommentieren.
Ist schwierig so durchzuschauen.

Aber wenn alle Schleifen nur bis 10 laufen, wieso
sollte es Deinem Programm dann einfallen auch von dem
11 Benutzer den Highscore zu sortieren.
Ich würde da mal drüber nachdenken.

Grüße
Klaus

marabu 11. Mär 2006 14:42

Re: Textdatei sortieren
 
Hallo.

Den Fehler in deinem Code hat dir Klaus schon nahe gebracht. Ich möchte dir noch ein paar Verbesserungsmöglichkeiten aufzeigen. Schon beim Schreiben deiner Spielstände solltest du darauf achten, dass nicht mehr als die maximale Zahl von Einträgen weggeschrieben werden. Das schrittweise Aufbauen der Bestenliste geschieht zweckmäßigerweise durch Einfügen an der richtigen Stelle - damit entfällt jedes Sortieren. Du schreibst die Bestenliste geordnet auf die Festplatte und liest sie von dort wieder geordnet ein. Spieler und Spielstand solltest du zumindest intern nicht getrennt behandeln: (ungetestet - heißt: die Fehler musst DU suchen)

Delphi-Quellcode:
type
  TScore = record
    Player: String;
    Score: Cardinal;
  end;

  TScores = array of TScore;

const
  MAX_SCORES = 10;

var
  Scores: TScores;

procedure LoadScores(
  var scores: TScores;
  fn: TFileName
);
var
  i, index: Integer;
  s: TStrings;
begin
  SetLength(scores, 0);
  if FileExists(fn) then
  begin
    s := TStringList.Create;
    s.LoadFromFile(fn);
    SetLength(scores, s.Count div 2);
    for i := Low(scores) to High(scores) do
      with scores[i] do
      begin
        Score := StrToInt(s[i * 2]);
        Player := s[Succ(i * 2)];
      end;
    s.Free;
  end;
end;
Einen neuen Spielstand kannst du in das einmal geordnete Array leicht eintragen:

Delphi-Quellcode:
procedure AddScore(
  var scores: TScores;
  const player: String;
  const score: Cardinal
);
var
  i, iNew: Integer;
begin
  iNew := Length(scores);
  if iNew < MAX_SCORES then
    SetLength(scores, Succ(Length(scores)));
  for i := Low(scores) to High(scores) do
    if (i = iNew) or (scores[i] < score) then
    begin
      if i < High(scores) then
        Move(scores[i], scores[Succ(i)], Pred(Length(scores) - i));
      scores[i].Player := player;
      scores[i].Score := score;
    end;
end;
Die Routine zum Speichern könnte dann so aussehen:

Delphi-Quellcode:
procedure SaveScores(
  scores: TScores;
  fn: TFileName
);
var
  i: Integer;
begin
  // den Code hier möchtest du vielleicht selbst schreiben
end;
Grüße vom marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz