Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Problem mit TFileStream


sunday_2 - Do 02.01.03 18:07
Titel: Problem mit TFileStream
Hi,

erstens 'Frohes neues Jahr' :party:
zweitens mein Problem. Ich will ein TFileSteam auslesen, indem ich ein Array habe. Ich übergebe auch die Größe des Arrays, es klappt leider trotzdem nicht.

Ich poste mal etwas Code:


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:
procedure Tfun_football.Statistik_allgemein();
var i,j: integer;
    Anzahl_Spieler: Integer;
    Anzahl_game: Integer;
    Anzahl_Mannschaften: Integer;
    STStart:Integer;
begin
        Anzahl_Spieler:= StrToInt(regeln.anzahl_Spieler);
        Anzahl_Mannschaften:= StrToInt(regeln.Anzahl_mannschaften);
        Anzahl_game := Anzahl_Spieler * Anzahl_Mannschaften;
        if FileExists(ExtractFilePath(ParamStr(0))+'Statistik_allgemein.kpt') = false then
           begin
           STGame:= nil; //STGame leeren, da die Datei ausgelesen wurde.
           STStart:=0;    //Zähler zurücksetzen
           end
        else
           STStart:= FStatistik.Size-1;
        SetLength(STGame,STStart+Anzahl_game);// Länge von STGame festlegen(Größe des Streams + Größe von game)
        // STGame füllen
        for i:= 0 to Anzahl_game-1 do
        for j:= 0 to StrToInt(regeln.anzahl_schuss) do
        begin
           STgame[STStart+i].Punktekonto[j]:= game[i].Punktekonto[j];// hier springt er ständig raus!!!
           STGame[STStart+i].Speedkonto[j] := game[i].Speedkonto[j];
           STGame[STStart+i].Name:= game[i].Name;
           STGame[STStart+i].Vorname:= game[i].Vorname;
           STGame[STStart+i].Mannschaft:= game[i].Mannschaft;
        end;
        FStatistik:= TFileStream.Create(ExtractFilePath(ParamStr(0))+'Statistik_allgemein.kpt',fmCreate);
        try
           FStatistik.WriteBuffer(Statistik.schussnr,SizeOf(Statistik.schussnr));
           for i:= 0 to STStart + Anzahl_game  do
           for j:= 0 to StrToInt(regeln.anzahl_schuss) do
              begin
                 FStatistik.WriteBuffer(STGame[i].Punktekonto[j],SizeOf(STGame[i].Punktekonto[j]));
                 FStatistik.WriteBuffer(STGame[i].Speedkonto[j],SizeOf(STGame[i].Speedkonto[j]));

              end;
              FStatistik.WriteBuffer(statistik.spielnr,SizeOf(Statistik.Spielnr));
              FStatistik.WriteBuffer(statistik.Wiederholung_spiel,SizeOf(Statistik.Wiederholung_spiel));
              FStatistik.WriteBuffer(statistik.schussnr,SizeOf(Statistik.Schussnr));
        finally
           FStatistik.Free;
        end;
end;

zur Erklärung: das Array game wird pro Spiel erstellt und danach wieder gelöscht. Das Array STGame soll die Werte aus game übernehmen und im zweiten Spiel die neuen Werte anhängen. Das soll solange gehen, bis die Datei von anderer Seite ausgelesen und zerstört wird.


Tino - Fr 03.01.03 10:43

Hallo,

was klappt denn jetzt nicht?

Gruß
TINO


sunday_2 - Fr 03.01.03 11:05

Hi Tino,

Das Programm springt bei
STgame[STStart+i].Punktekonto[j]:= game[i].Punktekonto[j];
raus. Beim Durchsteppen gibt er mir STStart := 0, i:= 0, j:= 0.
game[0].Punktekonto[0] hat auch einen Punktwert. Trotzdem schmiert er hier direkt ab. Das heißt er springt nach der Fehlermeldung aus der Schleife und springt direkt bis
FStatistik.Free;


Keldorn - Fr 03.01.03 16:34

Hallo

Tino hat folgendes geschrieben:

was klappt denn jetzt nicht?

Zitat:

Das heißt er springt nach der Fehlermeldung aus der Schleife

Es soll Hellseher geben die an der Stelle A:=B sofort erkennen können was passiert. Wenn Du nicht ewig warten willst, bis so ein Hellseher dein Post liest, wäre es vielleciht auch mal nicht schlecht, uns zu sagen, WAS für eine Fehlermeldung denn nu erscheint.


Quelltext
1:
 for j:= 0 to StrToInt(regeln.anzahl_schuss) do                    

wo wie was ist regeln.anzahl_schuss ?
enthält regeln.anzahl_schuss auch wirklich einen Zahlenwert und nicht z.B. '' ?

Auch scheinen noch Teile vom Code zu fehlen:

Quelltext
1:
STStart:= FStatistik.Size-1;                    

Fstatistik wird aber erst später erzeugt. Selbst wenn es existiert, fehlt dann ein free.

Mfg Frank


Keldorn - Fr 03.01.03 16:44

eines noch:


Quelltext
1:
STGame:= nil; //STGame leeren, da die Datei ausgelesen wurde.                    

weiß nicht recht, halte ich für gefährlich. Habe aber jetzt nur D3 hier und kann nix mit dynam. Arrays ausprobieren.
probier mal Setlength(stgame,0) um das array zu leeren

Mfg Frank


sunday_2 - Fr 03.01.03 16:54

Keldorn hat folgendes geschrieben:

Es soll Hellseher geben die an der Stelle A:=B sofort erkennen können was passiert. Wenn Du nicht ewig warten willst, bis so ein Hellseher dein Post liest, wäre es vielleciht auch mal nicht schlecht, uns zu sagen, WAS für eine Fehlermeldung denn nu erscheint.

Die Fehlermeldung lautet
Exception der Klasse EAccessViolation aufgetreten. Meldung: Zugriffsverletzung bei Adresse 005418CA im Modul 'KP_Fun_Football.exe'. Schreiben von Adresse 00000012. Prozeß wurde angehalten.

regeln.Anzahl_schuss ist ein auf jeden Fall mit einem Zahlenwert gefüllt.

TStart:= FStatistik.Size-1;
Das habe ich mittlerweile geändert. Hier der geänderte Code:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
SetLength(STGame,length(STGame)+Anzahl_game);
        SetLength(STGame[0].Punktekonto,StrToInt(regeln.anzahl_schuss));
        SetLength(STGame[0].Speedkonto,StrToInt(regeln.anzahl_schuss));
        STStart:=length(STGame);
        for i:= 0 to Anzahl_game-1 do
        for j:= 0 to StrToInt(regeln.anzahl_schuss) do
        begin
           STgame[STStart+i].Punktekonto[j]:= game[i].Punktekonto[j];
           STGame[STStart+i].Speedkonto[j] := game[i].Speedkonto[j];
           STGame[STStart+i].Name:= game[i].Name;
           STGame[STStart+i].Vorname:= game[i].Vorname;
           STGame[STStart+i].Mannschaft:= game[i].Mannschaft;
        end;

Die Fehlermeldung am Anfang der Schleife bleibt allerdings.
Ich hab allerdings absolut keine Ahnung warum.


Keldorn - Fr 03.01.03 21:25

da sind noch ein paar Sachen:


Quelltext
1:
2:
3:
4:
5:
        SetLength(STGame,length(STGame)+Anzahl_game);
...
        STStart:=length(STGame);
....
         STgame[STStart+i].Punktekonto[j]:= game[i].Punktekonto[j];

mit STStart:=length(STGame) -> ststart=Ende des Arrays befindeset du dich mit STgame[STStart+i].Punktekonto[j] außerhalb des gültigen Array-Bereiches.


Quelltext
1:
2:
for j:= 0 to StrToInt(regeln.anzahl_schuss) do 
STgame[STStart+i].Punktekonto[j]:= game[i].Punktekonto[j];

wenn Punktekonto ein Array ist, das mit Index0 statt 1 beginnt, ist das letzte Item [count-1]. Also for j:= 0 to (StrToInt(regeln.anzahl_schuss)-1) do


Quelltext
1:
2:
SetLength(STGame,length(STGame)+Anzahl_game);
        SetLength(STGame[0].Punktekonto,StrToInt(regeln.anzahl_schuss));

wenn punktekonto auch ein dyn. Array ist, langt das hier nicht.
die Arraygröße von STGame[1].Punktekonto ist nicht geändert wurden. Das müßte die Zugriffverletzung sein, da du auf etwas zugreifen willst, was es nicht gibt.
Wenn, dann mußt Du alle Punktekonto-array von STgame-array mit setlength setzen. Das gleiche gilt auch für das game-array.

Mfg Frank