Autor Beitrag
Frankle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Sa 27.07.02 17:05 
Hallo!
An beschriebener Stelle bekomm ich nen Fehler. Wieso des denn? *frag

ausblenden volle Höhe 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:
procedure tmainform.load_memos;
type
 TMyMemos=record
  Tmemo1: TStringlist;
  Tmemo2: TStringlist;
  Tmemo3: TStringlist;
 end;
var
 Strom: TFilestream;
 MyMemos: TMyMemos;
 i: integer;
begin
with MyMemos do
 begin
 Tmemo1:=TStringlist.Create;
 Tmemo2:=TStringlist.Create;
 Tmemo3:=TStringlist.Create;
 end;

 try
 Strom:=TFileStream.Create('./data/news.fk',fmOpenRead);
 Strom.Read(MyMemos,sizeof(TMyMemos));
  {anzeigen}
{Hier tritt EAccessViolation auf}
  for i:=0 to mymemos.Tmemo1.Count do
   begin
   ueberw_memo.Lines[i]:=mymemos.Tmemo1.Strings[i];
   enD;
  for i:=0 to mymemos.Tmemo2.Count do
   begin
   kauf_memo.Lines[i]:=mymemos.Tmemo2.Strings[i];
   enD;
  for i:=0 to mymemos.Tmemo3.Count do
   begin
   verkauf_memo.Lines[i]:=mymemos.Tmemo3.Strings[i];
   enD;
 finally
 strom.free;
 with mymemos do
  begin
  Tmemo1.free;
  tmemo2.free;
  tmemo3.free;
  end;
 end;
end;

_________________
---------------------------
God Safe QUEEN
"The Show Must Go On"
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: Sa 27.07.02 19:09 
Hallo,

ohne das ganze jetzt genauer unter die Lupe genommen zu haben würde ich mal auf diesen Pfad Tippen:

ausblenden Quelltext
1:
Strom:=TFileStream.Create('./data/news.fk',fmOpenRead);					


In deinen Dephi programmen kannst du für gewöhnlich nicht mit dem Verzeichnis . arbeiten außerdem wird unter windows der \ anstelle des / verwendet.
Wie du das erste Problem lösen kannst erfährst du hier.
Frankle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: So 28.07.02 00:35 
Titel: Hallo
. steht nich für ein Verzeichnis.
So..ich hab die Sache mal überarbeitet...jedoch zeigt er nach dem Laden jeweils im Memo nur die 1. Zeile an

ausblenden volle Höhe 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:
procedure tmainform.load_memos;
type
  TInhalte=record
   nr1: array[0..200] of string[100];
   nr2: array[0..200] of string[100];
   nr3: array[0..200] of string[100];
  end;
var
  Strom: TFileStream;
  Inhalte: TInhalte;
  i: integer;
begin
 try
 Strom:=TFileStream.Create('./data/news.fk',fmOpenRead);
 Strom.Read(Inhalte,sizeof(TInhalte));
 finally
 strom.free;
 end;
 for i:=0 to ueberw_memo.Lines.count do
  begin
  ueberw_memo.Lines[i]:=inhalte.nr1[i];
  end;
 for i:=0 to kauf_memo.Lines.count do
  begin
  kauf_memo.Lines[i]:=inhalte.nr2[i];
  end;
 for i:=0 to verkauf_memo.Lines.count do
  begin
  verkauf_memo.Lines[i]:=inhalte.nr3[i];
  end;
end;

procedure tmainform.save_memos;
type
  TInhalte=record
   nr1: array[0..200] of string[100];
   nr2: array[0..200] of string[100];
   nr3: array[0..200] of string[100];
  end;
var
  Strom: TFileStream;
  Inhalte: TInhalte;
  i: integer;
begin
for i:=0 to ueberw_memo.Lines.Count do
 begin
 inhalte.nr1[i]:=ueberw_memo.lines[i];
 end;
for i:=0 to kauf_memo.Lines.Count do
 begin
 inhalte.nr2[i]:=kauf_memo.lines[i];
 end;
for i:=0 to verkauf_memo.Lines.Count do
 begin
 inhalte.nr3[i]:=verkauf_memo.lines[i];
 end;
 try
 Strom:=TFileStream.create('./data/news.fk',fmCreate);
 Strom.Write(Inhalte,sizeof(TInhalte));
 finally
 Strom.free;
 end;
end;

_________________
---------------------------
God Safe QUEEN
"The Show Must Go On"
GPF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 85



BeitragVerfasst: So 28.07.02 02:45 
Ich versuche es mal direkt 'on the fly' - ohne den Code zu testen.
Irgendwie hast Du eine sehr umständliche, unschöne und ressourcenfressende Lade bzw. Speicherroutine geschrieben. Die Lösung ist denkbar einfach!
Zur Vereinfachung habe ich die Try...Finally Blöcke ausgelassen.

Zuerst die save_memos Prozedur:

ausblenden 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:
procedure TMainForm.Save_Memos;
var s:string;
      fs:TFileStream
      len:integer;
begin
  fs:=TFileStream.Create(IncludeTrailingBackSlash(ExtractFilePath(application.Exename))+'data\news.fk',fmCreate); 
  // ein direkter Bezug wie Du ihn benutzt funktioniert nur begrenzt. Änderst Du den aktuellen Pfad Deiner Anwendung z.B. über chDir landest Du in einem anderen Ordner!!

  s:=ueberw_memo.text; //memo.text enthält den kompletten Memotext inkl. Zeilenumbrüche
  len:=length(s);
  fs.Write(len, SizeOf(len)); //Längeninformationen für das erste Memo speichern - wird zum Laden benötigt
  if len>0 then  //Nur Speichern wenn Memo nicht leer
     fs.Write(s[1], Len); //schreibe ab Position s[1] len Zeichen in den Stream

  s:=kauf_memo.text; //memo.text enthält den kompletten Memotext inkl. Zeilenumbrüche
  len:=length(s);
  fs.Write(len, SizeOf(len)); //Längeninformationen für das zweite Memo speichern - wird zum Laden benötigt
  if len>0 then  //Nur Speichern wenn Memo nicht leer
     fs.Write(s[1], Len); //schreibe ab Position s[1] len Zeichen in den Stream
  
  s:=verkauf_memo.text; //memo.text enthält den kompletten Memotext inkl. Zeilenumbrüche
  len:=length(s);
  fs.Write(len, SizeOf(len)); [i]//Längeninformationen für das dritte Memo speichern - wird zum Laden benötigt[/i]
  if len>0 then  //Nur Speichern wenn Memo nicht leer
     fs.Write(s[1], Len); //schreibe ab Position s[1] len Zeichen in den Stream
  
  fs.Free;
end;



Das Laden funktioniert ähnlich:

ausblenden 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:
procedure TMainForm.Load_Memos;
var s:string;
      fs:TFileStream
      len:integer;
begin
  fs:=TFileStream.Create(IncludeTrailingBackSlash(ExtractFilePath(application.Exename))+'data\news.fk', fmOpenRead); 
  // ein direkter Bezug wie Du ihn benutzt funktioniert nur begrenzt. Änderst Du den aktuellen Pfad Deiner Anwendung z.B. über chDir landest Du in einem anderen Ordner!!

  fs.Read(len, SizeOf(Len)); //Länge des ersten Memofeldes lesen
  SetLength(s, Len);  //Die Länge von S anpassen - wichtig, da wir gleich direkt auf die Speicherzellen zugreifen
  if Len>0 then //Bedingung ist hier wichtig, da fs.read(beliebigeVariable, 0); eine Exception wirft!!!
    fs.Read(s[1], Len); //schreibe an die Speicherzelle des ersten Zeichens von s den Inhalt des ersten, gespeicherten Memofeldes
  ueberw_memo.text:=s; //Memoinhalt ersetzen

  fs.Read(len, SizeOf(Len)); //Länge des zweiten Memofeldes lesen
  SetLength(s, Len);  //Die Länge von S anpassen - wichtig, da wir gleich direkt auf die Speicherzellen zugreifen
  if Len>0 then //Bedingung ist hier wichtig, da fs.read(beliebigeVariable, 0); eine Exception wirft!!!
    fs.Read(s[1], Len); //schreibe an die Speicherzelle des ersten Zeichens von s den Inhalt des zweiten, gespeicherten Memofeldes
  kauf_memo.text:=s; //Memoinhalt ersetzen

  fs.Read(len, SizeOf(Len)); //Länge des dritten Memofeldes lesen
  SetLength(s, Len);  //Die Länge von S anpassen - wichtig, da wir gleich direkt auf die Speicherzellen zugreifen
  if Len>0 then //Bedingung ist hier wichtig, da fs.read(beliebigeVariable, 0); eine Exception wirft!!!
    fs.Read(s[1], Len); //schreibe an die Speicherzelle des ersten Zeichens von s den Inhalt des dritten, gespeicherten Memofeldes
  verkauf_memo.text:=s; //Memoinhalt ersetzen

  fs.Free;
end;



Was lernen wir daraus?
Wenn wir statische Variablen speichern wollen (also Felder mit fester Größe, wie Char, Integertypen, booleische Felder, Mengen, Records mit fester Größe, etc) und die Position bekannt ist dann können wir direkt den Speicherinhalt ersetzen.

Strings, Stringlisten und andere dynamische Datentypen haben leider keine feste Größe. Deshalb müssen wir ersteinmal die Länge speichern, reservieren dann exakt soviel Speicher (bei Strings über Setlength) wie benötigt, damit dann im letzten Schritt unsere Daten endlich einlesen können - genau die Anzahl Bytes wie wir in dem Größenfeld gespeichert haben, natürlich nur, falls ungleich 0

MfG
GPF
Frankle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Di 30.07.02 13:52 
Titel: Antwort
Hi!
Danke....das nenn ich 'ne Antwort :D

_________________
---------------------------
God Safe QUEEN
"The Show Must Go On"
BlackOrpheus
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Mi 07.08.02 23:25 
Titel: Am Rande
Nur noch als Info am Rande!

Wenn du mit einer for Schleife arbeiten willst musst Du bedenken, daß
der größte Index immer .Count - 1 ist.

d.h. in eiem z.B. Memo mit zwei Zeilen ist .Count = 2 aber die Indizes der Spalten sind .Lines[0] & Lines[1].

Wenn Deine for Schleife nun von 0 dis 2 läuft gibts bei .Lines[2] eine Zugriffsverletzung.

In diesem Sinne ...