![]() |
Exeption - Woher?
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
in der Schule programmieren wir aktuell ein kleines Übungsprojekt, das eine Buchliste (Datenstruktur siehe Anhang) auslesen und ein TBuch schreiben soll. Wir benutzen übrigens Delphi 6. Ein Buch ist als folgendes deklariert (in eigener Unit mBuch):
Delphi-Quellcode:
Der Quellcode des restlichen Projekts:
unit mBuch;
interface type TBuch = class(TObject) private {} public ID: integer; Thema: string; Autor: string; Titel: string; Ort: string; Erscheinungsjahr: integer; Verlag: string; end; implementation end.
Delphi-Quellcode:
Beim ausführen von LineExtract gibts dann leider immer eine Exception der Klasse EAccessViolation (Zugriffsverletzung).
unit mBuchliste;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, mBuch, StdCtrls; type TfMain = class(TForm) procedure FormCreate(Sender: TObject); private {} protected procedure LineExtract; public Buchliste: Array[1..1602] of TBuch; end; var fMain: TfMain; s: string; z: integer; const MyDat ='Buecher.txt'; implementation {$R *.dfm} function PosEx(const Substr: string; const S: string; Offset: Integer): Integer; begin if Offset <= 0 then Result := 0 else Result := Pos(Substr, Copy(S, Offset, Length(S))); if Result <> 0 then Result := Result + Offset - 1; end; procedure TfMain.LineExtract; var x,y: integer; begin x := 0; y := 1; For x := 1 to 7 do begin If x <> 7 then begin Case x of 1: Buchliste[z].ID := StrToInt(Copy(s, y, PosEx(';', s, y) - y)); 2: Buchliste[z].Thema := Copy(s, y, PosEx(';', s, y) - y); 3: Buchliste[z].Autor := Copy(s, y, PosEx(';', s, y) - y); 4: Buchliste[z].Titel := Copy(s, y, PosEx(';', s, y) - y); 5: Buchliste[z].Ort := Copy(s, y, PosEx(';', s, y) - y); 6: begin If Copy(s, y, PosEx(';', s, y) - y) <> '' then Buchliste[z].Erscheinungsjahr := StrToInt(Copy(s, y, PosEx(';', s, y) - y)) Else if Copy(s, y, PosEx(';', s, y) - y) = '' then Buchliste[z].Erscheinungsjahr := 0; end; end; y := PosEx(';', s, y) + 1; end Else if x = 7 then begin Buchliste[z].Verlag := Copy(s, y, Length(s) - y + 1); end; end; end; procedure ReadIn; var datei: Textfile; begin z := 0; assignfile(datei,MyDat); reset(datei); while not EOF(datei) do begin readln(datei,s); z := z + 1; fMain.LineExtract; end; closefile(datei); end; procedure TfMain.FormCreate(Sender: TObject); begin ReadIn; end; end. Keiner - nichtmal der Lehrer :P - weiss woher die kommmt. Hat jemand eine Idee? mfg fortuneNext |
Re: Exeption - Woher?
Zitat:
Du hast ein Array von Objekten, die Du nirgends erzeugst, greifst aber trotzdem darauf zu? :gruebel: Das kann ja gar nicht gehen ;) Setze ein Buchliste[z] := TBuch.Create() und es sollte doch eigentlich gehen. Btw hast Du also eine Klasse, die nichts anderes ist als ein Datencontainer. Hätte es dafür ein Record nicht auch getan? Damit würde es nämlich auch so funktionieren ;) |
Re: Exeption - Woher?
Ja, ein Record hätte es auch getan!
[OT] Was'n dat für'n Lehrer? [/OT] |
Re: Exeption - Woher?
Diese Logik erschließt sich mir nicht so recht:
Zitat:
|
Re: Exeption - Woher?
mhhh... scheint mir 'n mix zwischen konsolapp und fensterapp zu sein... (z.b. readln im constructor). der aufbau scheint mir da auch so 'n mix aus objektorientierung und prozeduraler zu sein... class buch in verbindung mit record...
tja, als übungsprobjekt schon sehr gut, da hast du noch 'n bischen arbeit vor dir, bis es rund läuft ... :-) PS: mit den tipp von leddl, sollt es klappen... |
Re: Exeption - Woher?
Ah, danke für die ganzen konstruktiven Kommentare :-)
Werde bald mal alles ausprobieren... das mit dem Create ist natürlich klar, hatte ich ganz vergessen :-D Und naja... zur Unterrichtung junger Informatiker wird in der Regel kein kompetentes Personal genutzt... Und generell gehts in der Schule ja nicht dadrum, sinnvolle, gut laufende, simpel geschriebene und funktionierende Programme zu schreiben, sondern irgendwelche überhaupt nicht passenden Komponenten dabei zu verwenden (Record - Typ)... |
Re: Exeption - Woher?
Liste der Anhänge anzeigen (Anzahl: 1)
Okay... der Create war die Lösung.
Nun versuchen wir, die eingelesenen Daten in ein StringGrid einzutragen. Dazu 2 Fragen: 1. Es wird wieder eine Exception ausgelöst... völlig sinnlos, beim lesen von Eintrag 1598 und den folgenden 4. Die kann zwar durch einen Try-Block umgangen werden, was aber eine sehr schlampige Lösung ist und nicht die Frage beantwortet, woher sie kommt. Das seltsame daran ist, dass das Programm trotzdem gut läuft, alle Sachen werden korrekt dargestellt etc. 2. Jetzt möchten wir die Sachen sortieren, nach den div. Datentypen (also z.B. nach ID, nach Autor etc). Das wollten wir auslösen, indem man auf die "Fixed-Cols" drückt (oben wo die Beschriftung ist). Ein OnCellSelect geht leider nicht, da sich die Dinger nicht anklicken lassen. Gibt es da irgendeine Lösung oder werden wir eigene Buttons einbauen müssen? Also die Frage ist, lassen sich die Fixed Einträge zu Buttons umfunktionieren?. Danke! mfg |
Re: Exeption - Woher?
- Bereichprüfung einschalten.
- Breakpoints setzen. - Debugger ausgiebig benutzen. |
Re: Exeption - Woher?
Jag das Programm doch durch den Debugger, dann siehst du welcher Befehl diesen Fehler auslöst und dann vielleicht auch warum
|
Re: Exeption - Woher?
Ich weiss ja woher der Fehler kommt.
Delphi-Quellcode:
Bloß wieso bringt das einen Fehler?
StrGrid_Buchliste.Cells[0,x] := IntToStr(Buchliste[x].ID);
Und vor allem erst bei Eintrag 1598-1602? Und warum klappts dann auch noch trotzdem? oO Für mich ein mysterium... das kompetente Lehrpersonal weiss es auch nicht ^^ |
Re: Exeption - Woher?
Was steht den in ID?
|
Re: Exeption - Woher?
Der Fehler kann ja nur in Buchliste[x] sein. Was für einen Wert hat x, wenn der Fehlerauftritt?
|
Re: Exeption - Woher?
Liste der Anhänge anzeigen (Anzahl: 1)
hier mal 'n kleines testprogramm:
Delphi-Quellcode:
Edit://Code umformatiert, da die codedarststellung in der DP recht eigensinnig ist und macht was sie will ... hoffe so ist es besser lesbar
UNIT Unit1;
INTERFACE USES Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, csv; TYPE TForm1 = CLASS(TForm) sg: TStringGrid; PROCEDURE FormCreate(Sender: TObject); PROCEDURE FormDestroy(Sender: TObject); private { Private-Deklarationen } sl: TStringList; public { Public-Deklarationen } END; VAR Form1: TForm1; IMPLEMENTATION {$R *.dfm} PROCEDURE TForm1.FormCreate(Sender: TObject); VAR csv: tCSV; i: integer; j: integer; BEGIN sl := TStringList.Create; sl.LoadFromFile('Buecher.txt'); csv := tCSV.Create; TRY sg.ColCount := 8; sg.RowCount := sl.Count + 1; FOR i := 0 TO sl.Count - 1 DO BEGIN csv.Analyze(sl.Strings[i]); sg.Cells[0, i + 1] := IntToStr(i + 1); FOR j := 0 TO csv.Count - 1 DO sg.Cells[j + 1, i + 1] := csv.Columns[j]; END; FINALLY csv.Free; END; END; PROCEDURE TForm1.FormDestroy(Sender: TObject); BEGIN sl.Free; END; END. Edit2: Kommentar von vorhin noch mal hinzugefügt, da der Editor diese vorloren hat...: Wenn Du dir die zeilen ansiehst, sollte dir etwas bei auffallen... |
Re: Exeption - Woher?
Warum muss die StringList global sein?
|
Re: Exeption - Woher?
muss nicht, nur schnell reingehackt...
so, besser?
Delphi-Quellcode:
UNIT Unit1;
INTERFACE USES Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, csv; TYPE TForm1 = CLASS(TForm) sg: TStringGrid; PROCEDURE FormCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } END; VAR Form1: TForm1; IMPLEMENTATION {$R *.dfm} PROCEDURE TForm1.FormCreate(Sender: TObject); VAR csv: tCSV; i: integer; j: integer; sl: TStringList; BEGIN sl := TStringList.Create; TRY sl.LoadFromFile('Buecher.txt'); csv := tCSV.Create; TRY sg.ColCount := 8; sg.RowCount := sl.Count + 1; FOR i := 0 TO sl.Count - 1 DO BEGIN csv.Analyze(sl.Strings[i]); sg.Cells[0, i + 1] := IntToStr(i + 1); FOR j := 0 TO csv.Count - 1 DO sg.Cells[j + 1, i + 1] := csv.Columns[j]; END; FINALLY csv.Free; END; FINALLY sl.Free; END; END; END. |
Re: Exeption - Woher?
Wenn du schon fragst: Warum zwei Try-Finally-Blöcke?
Aber was ich viel spannender finde: wo kommt die csv-Unit her? Bei Delphi7 hab ich die irgendwie nicht. Oder bin ich blind? |
Re: Exeption - Woher?
die zwei try finally kommen daher, weil bei jeden create etwas schiefgehen kann und da das objekt noch nicht initialisiert wäre... ein abprüfen auf NIL scheidet aus, da die objekte auf den stack angelegt sind und somit vor dem initialisieren irgendeinen wert aufweisen. deswegen der verschachtelte try finally...
die CSV unit ist selbst gebastelt, hatte keine lust die stringzerlegung mit der hand nachzuvollziehen, obgleich fortuneNext im ersten post etwas entsprechendes hatte. alzheimer hatte auch mal eine CSV unit in der opensource sparte gepostet... aber die stringzerlegung war ja hier auch nicht das problem... deswegen erlaubte ich mir die erleichterung ..., ausserrdem will ich ihm ja auch nicht die ganze arbeit abnehmen ... ;-) schöne grüsse und noch 'n schönen abend GG |
Re: Exeption - Woher?
Zitat:
|
Re: Exeption - Woher?
Zitat:
Ein Hinweis wäre da das Mindeste gewesen. |
Re: Exeption - Woher?
Also ich muss sagen, das Beispiel verstehe ich wirklich nicht. Ich sehe zwar die Logik des Codes so einigermaßen ein (auch wenn ich die Unit nicht kenne), aber das hilft mir bei der Suche nach meinem Fehler überhaupt nicht.
x ist wie gesagt 1598... und was ich auch schon schrieb (siehe post 1):
Delphi-Quellcode:
Weiss einer wo das Problem liegt?
type
TBuch = class(TObject) private {} public ID: integer; Thema: string; Autor: string; Titel: string; Ort: string; Erscheinungsjahr: integer; Verlag: string; end; Manchmal wünscht ich, in diesem Fach könnte einem der Lehrer zumindest manchmal weiterhelfen... |
Re: Exeption - Woher?
Hi,
eines deiner Probleme dürfte die Tatsache sein, dass die Datei BUECHER.TXT nur 1597 Datensätze aufweist. Grüße vom marabu |
Re: Exeption - Woher?
[wegen Nicht-Beachtung gelöscht]
|
Re: Exeption - Woher?
Oh gott... ich glaubs nicht... was stellt uns der Kerl eigentlich für Material zur Verfügung... erst war da in einer Zeile ein Fehler der Datenstruktur, waren 2 Autoren mit ; getrennt und wir suchen uns nen Wolf weil ders nich kapiert, und jetzt sowas...
xD okay danke...das ist natürlich ein doofer fehler... |
Re: Exeption - Woher?
Zitat:
![]() PS: das war wohl ditaktik, ihr sollt ja progrmmieren lernen, und dazu gehört auch die fehlersuche mit zu ... :-) jetzt mal klartext, dein .RAR kann ich nicht entziffern, aber meine :glaskugel: erzählt mir, dass du ein array definierter länge hast, das du beim einlesen nicht ordentlich initialisiert... beim auslesen, stollperst du über die fehlerhaften initialisierungen... und das bringt die fehler ... hier kannst (a) ordentlich initialisieren und (b) beim auslesen vernünftig darauf reagieren... z.b.
Delphi-Quellcode:
dann sollt es auch keine fehlermeldungen mehr geben, und du hast (a) gelernt deine datenstrukturen zu initialsieren und (b) eine ordentliche fehlerbehandlung aufzubauen :-)
fillchar(myarray, sizeof(myarray), 0);
if assigned(myarray[xyz]) then myObject(myarray[xyz]).dosomething; <HTH> GG |
Re: Exeption - Woher?
Naja, die Taktik wars gewiss nicht ;) Sonst wär nicht der Satz gekommen "Naja... keine Ahnung... müssen wir wohl mit dieser kleinen Ausnahme leben, ich wüsste auch nich woher sie kommt" xD
Gut, wir initialisieren dann mal richtig ab jetzt :) Zitat:
naja, wie soll man das abprüfen? Die fixed-cols sind leider nicht anklickbar, so gibt es überhaupt keinen Indikator... Und @ omata: sry... muss es wohl irgendwie überlesen haben :-/ jetzt fällts mir erst beim 2. durchschauen auf... xD |
Re: Exeption - Woher?
im übrigen, objekte werden im constructor automatisch initialisiert...
aber dein array, auch records, wie auch deine lokalen und globalen variablen musste mit der hand initialisieren :-) PS: Ordentlich initialiseren und vernünftig einrücken, erspart dir schlaflose nächte mit dem debugger :-) |
Re: Exeption - Woher?
Zitat:
Delphi-Quellcode:
ps: alternativ könntest auch 'n listview statt 'n stringgrid nehmen... :roll:
procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); var c, r: integer; begin TStringGrid(sender).MouseToCell(x, y, c, r); if mbLeft = button then begin StatusBar1.SimpleText := inttostr(c) + '/' + inttostr(r); end; end; |
Re: Exeption - Woher?
Mit dem Code weiss ich aber immernoch nicht auf welche Zelle jetzt gedrückt wurde... :-(
|
Re: Exeption - Woher?
Wieso nicht? Schau mal in der Hilfe nach, was MouseToCell macht.
|
Re: Exeption - Woher?
Achsooo... okay ich habs zuerst falsch verstanden :D ich dachte, es gibt nur die Mauskoordinaten aus... xD
Okay danke! :) Weiss zufällig noch einer wie ich einzelne Zellen editiere? Also haben die vielleicht Eigenschaften wie Farbe oder Textausrichtung? :-) Ansonsten wenn nicht auch egal... Danke an alle Helfer! :-) mfg edit ps: dank auflage des lehrers müssen wir leider ein stringgrid benutzen ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz