Autor |
Beitrag |
Johannes86
Hält's aus hier
Beiträge: 2
|
Verfasst: Mo 24.10.05 13:41
Ich bin dabei, einen Vokabeltrainer zu programmieren. Dabei wollte ich die Datenbank wie folgt definiert haben:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| PTMother = ^TMother; TMother = record Meaning: string; next:PTMother; end;
PTVoc = ^TVoc; TVoc = record foreign: string; mother: PTMother; Last_Tested: TDateTime; Create_Date: TDateTime; Tested_Times: Byte; Correct_Times: Byte; Was_Last_Correct: boolean; previous,next:PTVoc; end;
var Form1: TForm1; Vocs: PTVoc; |
Nun das Problem:
Mit dieser Struktur hab ich ein schnelles Einlesen und Auslesen schon erreicht, aber wenn man Vokabeln nicht speichern kann... Deshalb habe ich mir Tutorials zu Stream (Filestreams) durchgelesen usw... Und hab eine noch nicht funktionierende Lösung:
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: 64: 65: 66: 67: 68: 69:
| procedure load_data(filename:string; var Voc_List:PTVoc); var f: TFileStream; i,k: integer; j:Byte; s:TStrings; zs:string; ZVL:PTVoc; begin Form1.Caption:='Personal Vocabulary Trainer - ' + copy(filename,1+length(PChar(ExtractFilePath(ParamStr(0)))),length(filename)-length(PChar(ExtractFilePath(ParamStr(0))))+1); f:=TFileStream.Create(filename,fmOpenRead); try f.Position:=0; ZVL:=nil; s:=TStringList.Create; while f.Position<f.Size do begin Voc_List:=nil; new(Voc_List); Voc_List.previous:=nil; Voc_List.next:=nil; f.Read(i,SizeOf(i)); f.Read(Voc_List.foreign,i); s.Clear; f.Read(j,SizeOf(j)); for k:=1 to j do begin f.Read(i,SizeOf(i)); f.Read(zs,i); s[k-1]:=zs; end; Voc_List.mother:=Create_Mother(s); f.Read(Voc_List.Last_Tested,SizeOf(TDateTime)); f.Read(Voc_List.Create_Date,SizeOf(TDateTime)); f.Read(Voc_List.Tested_Times,1); f.Read(Voc_List.Correct_Times,1); f.Read(Voc_List.Was_Last_Correct,SizeOf(boolean)); if ZVL<>nil then begin ZVL.next:=Voc_List; ZVL.next.previous:=ZVL; end; ZVL:=Voc_List; end; finally f.Free; end; end;
procedure save_data(filename:string;Voc_List:PTVoc); var f: TFileStream; i: integer; j:Byte; begin Form1.Caption:='Personal Vocabulary Trainer - ' + copy(filename,1+length(PChar(ExtractFilePath(ParamStr(0)))),length(filename)-length(PChar(ExtractFilePath(ParamStr(0))))+1); f:=TFileStream.Create(filename,fmCreate); Reset_Vocs(Voc_List); try while Voc_List<>nil do begin i:=length(Voc_List.foreign); f.Write(i,SizeOf(i)); f.Write(Voc_List.foreign,i); j:=Count_Mother(Voc_List.mother); f.Write(j,SizeOf(j)); while Voc_List.mother<>nil do begin i:=length(Voc_List.Mother.Meaning); f.Write(i,SizeOf(i)); f.Write(Voc_List.Mother.Meaning,i); Voc_List.mother:=Voc_List.mother.next; end; f.Write(Voc_List.Last_Tested,SizeOf(TDateTime)); f.Write(Voc_List.Create_Date,SizeOf(TDateTime)); f.Write(Voc_List.Tested_Times,1); f.Write(Voc_List.Correct_Times,1); f.Write(Voc_List.Was_Last_Correct,SizeOf(boolean)); Voc_List:=Voc_List.next; end; finally f.Free; end; end; |
Also: Wer findet den Fehler und was hab ich dabei nicht beachtet!!
Vielen Dank schon im Voraus für Vorschläge.
Moderiert von raziel: Delphi-Tags hinzugefügt.
Moderiert von raziel: Titel geändert.
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mo 24.10.05 14:24
Hallo!
Es ist immer hilfreich, anzugegeben, was für ein Fehler überhaupt auftritt. Desweiteren solltest du dein Problem genauer eingrenzen. Wenn du weisst, daß du Schwierigkeiten mit dem Speichern hast, warum baust du nicht erst einmal Testcode, um dich speziell nur um dieses Problem zu kümmern? Wieso sollte sich nun irgendjemand die Mühe machen, dein unübersichtliches und kommentarloses Projekt zu debuggen?
Da es teilweise um Strings bzw. Records mit dynamischen Strings geht, wage ich mal einen Schuss ins Blaue:
Dynamische Strings sind nichts anderes als Zeiger auf einen bestimmten Bereich im Speicher. Wenn du sie ganz normal speicherst, landet nur der 4 Byte grosse Zeiger-Inhalt auf der Festplatte. Du musst also beim Lesen und Schreiben von Strings in einen Stream anders vorgehen. Suche mal nach LOADSTRFROMSTREAM / SAVESTRTOSTREAM.
Cu,
Udontknow
|
|
AG
      
Beiträge: 22
|
Verfasst: Mo 24.10.05 14:47
was für ein Fehler tritt denn übergaupt auf???
also, wenn ich mit Filestreams arbeite, und eigentlich eine vorhersehbare Struktur hab (also weiß, was (welcher Typ) genau als nächstes steht), arbeite ich mit TReader und TWriter, und den Funktionen
Reader.ReadInteger, ...Float, ...String, und so weiter... (beim einlesen) und
Writer.WriteInteger usw. beim abspeichern;
dann machste dir zu deinem Vokabeltyp 2 Funktionen
VokabelAbspeichern(var Reader:TReader) und
VokabelLesen(var Writer;TWriter); und 2 ListenFunktionen
ListeAbspeichern und ListeEinlesen;
in Listeabspeichern kommt dann
FileStream öffnen, Writer definieren, Anzahl der Vokabeln abspeichern (Writer.WriteInteger) und Vokabeln abspeichern (AktuelleVokabel.VokabelAbspeichern(Writer) ),
am Ende Writer und Stream freigeben;
In ListeEinlesen kommt:
ev. alte Liste freigeben
Liste erzeugen
FileStream öffnen
Reader definieren
Anzahl der Vokabeln einlesen (mit Reader.ReadInteger
pro Vokabel
Objekt erstellen (AktuelleVokabel:=TVokabel.Create)
Objekt einlesen (AktuelleVokabel.VokabelEinlesen(Reader) )
Objekt verketten
am Ende Reader und Stream freigeben
|
|
Johannes86 
Hält's aus hier
Beiträge: 2
|
Verfasst: Di 25.10.05 09:52
Titel: Vielen Dank erstmal für eure schnellen Antworten
Vielen Dank erstmal.
Ich werde mir jetzt erst mal eure Vorschläge anschauen und dabei gucken, was sich meiner Meinung nach am besten realisieren lässt. Ohne eure Hilfe wäre ich wahrscheinlich nicht so schnell darauf gekommen... Also vielen Dank...
Die Fehlermeldung ist übrigens:
"Im Projekt VocTrainer.exe ist eine Exception der Klasse EStringListError aufgetreten. Meldung: 'Listenindex überschreitet das Maximum (0)'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
Das ist die Fehlermeldung, wenn ich öffne. Und ich hab mal langsam durchgegangen, was der so macht, also während des Programmablaufs. Und: Wenn die Dateilänge Null ist, so springt er trotzdem in
while f.Position<f.Size do
begin
...
end;
herein!! Dabei ist eigentlich, wenn man sich die Zahlen anschaut f.Position garnicht kleiner als f.Size!! Irgendwie seltsam...
Aber da ich nun andere Anregungen habe, werde ich erstmal diese ausprobieren...
|
|
|