![]() |
Versuch hinter dem Dateiende zu lesen
Hey, stehe auf dem Schlauch. wo ist der Fehler?
Delphi-Quellcode:
Initialisiert wird so:
procedure TForm1.FillList;
var i:Integer; begin for i:=0 to sizeof(datei) do begin Seek(datei, i); Read(datei, data); ListView1.Items.Add; ListView1.Items[i].Caption:=data.Name; with ListView1.Items[i].SubItems do begin Add(data.Format); Add(data.Sprache); end; end; end;
Delphi-Quellcode:
Fehlermeldung: Versuch hinter dem Dateieinde zu lesen. Könnte ja einen try-except Block einbauen, aber das ist nicht so die feine Art...
procedure TForm1.FormCreate(Sender: TObject);
begin AssignFile(datei, 'index.dat'); IF FileExists('index.dat') THEN Reset(datei) else Rewrite(datei); filllist; end; Bitte somit jämmerlich um Hilfe! :-D |
Re: Versuch hinter dem Dateiende zu lesen
Hi DJ-SPM,
der Fehler liegt eindeutig hier:
Delphi-Quellcode:
sizeof(datei) gibt dir die Anzahl Datensätze in der Datei zurück. Nachdem die Indizierung bei 0 und nicht bei 1 beginnt, hört sie auch bei sizeof(datei)-1 auf.
for i:=0 to sizeof(datei) do begin
Greetz alcaeus |
Re: Versuch hinter dem Dateiende zu lesen
Also, ich finde es cool, dass dumir heute so viel hilfst, aber sizeof(datei)-1 bringt den gleichen Fehler...
|
Re: Versuch hinter dem Dateiende zu lesen
Hi DJ-SPM,
in welcher Zeile steht der Cursor sobald die Exception auftritt? in deinem Code sehe ich nämlich keinen weiteren Fehler. Greetz alcaeus |
Re: Versuch hinter dem Dateiende zu lesen
Delphi-Quellcode:
Hier mal mein Programmcode:
procedure TForm1.FillList;
var i:Integer; begin for i:=0 to sizeof(datei)-1 do begin Seek(datei, i); Read(datei, data); <---------------HIER ListView1.Items.Add; ListView1.Items[i].Caption:=data.Name; with ListView1.Items[i].SubItems do begin Add(data.Format); Add(data.Sprache); end; end; end;
Delphi-Quellcode:
Hab es net so mit Records... Will aber lernen ;-)
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, XPMan, ComCtrls; type TForm1 = class(TForm) ListView1: TListView; GroupBox1: TGroupBox; XPManifest1: TXPManifest; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; GroupBox2: TGroupBox; BitBtn1: TBitBtn; Label7: TLabel; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Edit7: TEdit; Label8: TLabel; procedure FormCreate(Sender: TObject); procedure BitBtn1Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure ListView1Click(Sender: TObject); private procedure FillList; procedure OpenInfo; public { Public-Deklarationen } end; TMovie = record Name :string[150]; Format :string[100]; CDs :string[1]; Ton :string[20]; Bild :string[20]; Sprache :string[20]; Gernre :string[20]; Kommentar:string[255]; end; var Form1 : TForm1; datei : file of TMovie; data : TMovie; implementation {$R *.dfm} procedure TForm1.FillList; var i:Integer; begin for i:=0 to sizeof(datei)-1 do begin Seek(datei, i); Read(datei, data); ListView1.Items.Add; ListView1.Items[i].Caption:=data.Name; with ListView1.Items[i].SubItems do begin Add(data.Format); Add(data.Sprache); end; end; end; procedure TForm1.OpenInfo; var i:Integer; begin Seek(datei, ListView1.Selected.Index); Read(datei, data); Label1.Caption:=data.Name; Label2.Caption:=data.Format; end; procedure TForm1.FormCreate(Sender: TObject); begin AssignFile(datei, 'index.dat'); IF FileExists('index.dat') THEN Reset(datei) else Rewrite(datei); filllist; end; procedure TForm1.BitBtn1Click(Sender: TObject); begin data.Name:=Edit1.Text; data.Format:=Edit2.Text; data.CDs:=Edit3.Text; data.Gernre:=Edit4.Text; data.Bild:=Edit5.Text; data.Ton:=Edit6.Text; data.Sprache:=Edit7.Text; seek(datei, filesize(datei)-1); write(datei, data); FillList; end; procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(IntToStr(sizeof(datei)-1)); end; procedure TForm1.ListView1Click(Sender: TObject); begin OpenInfo; end; end. EDIT: Die SizeOf(datei)-1 habe ich nach deinem Post erst eingebaut |
Re: Versuch hinter dem Dateiende zu lesen
:wall:
Dass mir das nicht früher aufgefallen ist: sizeof(datei) gibt dir nicht die anzahl records zurück, sondern die größe der filevariable. du musst filesize(datei)-1 verwenden. Und weil wir schon dabei sind: beim schreiben eines neuen records musst du den zeiger auf filesize(datei) setzen, sonst überschreibst du ja den letzten record. Greetz alcaeus |
Re: Versuch hinter dem Dateiende zu lesen
Darf ich dich Gott nennen?!?
Mir wäre es nie aufgefallen, aber jetzt wo du es sagst.... Super! Danke :thumb: |
Re: Versuch hinter dem Dateiende zu lesen
[OT]
Zitat:
[/OT] Greetz alcaeus |
AW: Versuch hinter dem Dateiende zu lesen
Habe denselben Fehler und Blicke grad net was da falsch ist :|
Ist mein projekt für Informatik und nunja ich verzweifel da dran. Mein Problem ist, dass das Programm entweder das Wort nicht bis ans Ende kopiert, oder ich den Datei-Fehler erhalte. Setze ich bei der Procedure löschen Filesize(woert)-2 ein kopiert mir es das nicht auf den letzten Platz, wenn ich Filesize(woert)-1 eingebe bekomme ich 'Versuch hinter dem Dateiende zu lesen.
Delphi-Quellcode:
Ich blick es nicht ....
procedure TForm1.Button5Click(Sender: TObject);
var key:String[25]; i:integer; h:integer; begin Assignfile(woert,'Wörterbuch.dat'); reset(woert); key:=Inputbox('Abfrage','Welches Wort löschen?(bitte das englische Wort eingeben)',''); for i := 1 to filesize(woert) do begin read(woert,Woerterbuch); if key=Woerterbuch[i].Englisch then begin h:=i; löschen(h); exit; end else showmessage('Das Wort steht nicht im Wörterbuch'); end; closefile(woert); end; Procedure löschen(h:integer); var m,Prüfung:Twoerterbuch2; j:integer; Warnung:String[1]; begin assignfile(woert,'Wörterbuch.dat'); reset(woert); for j := h to Filesize(woert)-1 do begin Read(woert,Woerterbuch); m[j]:=Woerterbuch[j]; Woerterbuch[j]:=Woerterbuch[j+1]; Woerterbuch[j+1]:=m[j]; write(woert,Woerterbuch); end; seek(woert,(Filesize(woert))-1); truncate(woert); closefile(woert); end; |
AW: Versuch hinter dem Dateiende zu lesen
Ich glaube da ist selbst FileSize() in Verbindung mit der For-Schleife nicht optimal (außer wenn [in seinem Fall] data nur 1 Byte groß ist)
per EOF(Datei) kannst du gucken, ob das Ende erreicht wurde. Da man die Anzahl der Lesebefehle nicht kennt, verwendet man nicht die inidizerte Schleife (for i) sondern eine "einfachere". Falls die Datei (IMMER) aus mindestens einem Datensatz besteht, so kann man dies mit der repeat until Schleife machen. Ansonsten nimmt man die While Do Schleife Beispielcodefetzen:
Delphi-Quellcode:
Im obrigen Beispiel ist die Position vom FilePointer auf 0 (beim Öffnen einer Datei immer 0); falls die Datei jedoch offen war und Dateioperationen durchgeführt wurden, muss dies nicht der Fall sein, deshalb eignet sich ein Seek(MeineDatei, 0) eventuell.
AssignFile(MeineDatei, DateiName);
{$I-} Reset(MeineDatei); {$I+} if IOResult <> NO_ERROR then // Datei existiert nicht, neu anlegen // NO_ERROR = 0 ReWrite(MeineDatei); while not EOF(MeineDatei) do begin Read(MeineDatei, DatenSatz); FügeDatenSatzInZbListe(DatenSatz); end; |
AW: Versuch hinter dem Dateiende zu lesen
Bei einer typisierten Datei-Variable gibt FileSize nicht die Dateigröße, sondern die Anzahl der Records an.
Delphi-Quellcode:
(RealSizeOfFile div RecSize)
|
AW: Versuch hinter dem Dateiende zu lesen
Achso, ok. Was bewirkt Seek() bei einer typisierten Datei? Springt er an die exakte Position, die angegeben wird, oder wird das intern mit der TypenGröße mültipliziert? Falls ja, dann würde das mit der For-Schleife auch funktionieren und der Fehler läge wo anders =/
|
AW: Versuch hinter dem Dateiende zu lesen
![]() Zitat:
|
AW: Versuch hinter dem Dateiende zu lesen
Ich denke dies ist nicht ganz unproblematisch;
Delphi-Quellcode:
LÖSCHEN wir auf eine geöffnete Datei ausgeführt (übrigens ein Hoch auf globale Variablen).
procedure TForm1.Button5Click(Sender: TObject);
var key:String[25]; i:integer; h:integer; begin Assignfile(woert,'Wörterbuch.dat'); reset(woert); ..... for i := 1 to filesize(woert) do begin read(woert,Woerterbuch); if key=Woerterbuch[i].Englisch then begin ... löschen(h); exit; end else ... end; closefile(woert); end; Procedure löschen(h:integer); ... begin assignfile(woert,'Wörterbuch.dat'); reset(woert); .. closefile(woert); Wenn schon global, dann aber reset und closefile auch global! Gruß K-H |
AW: Versuch hinter dem Dateiende zu lesen
Liste der Anhänge anzeigen (Anzahl: 1)
Ich weiß jetzt nicht nach wem ich mich richten soll.
Zitat:
Zitat:
Zitat:
Im Anhang ist dann mal meine Unit. |
AW: Versuch hinter dem Dateiende zu lesen
Zitat:
Zuerst öffnest Du die Datei (assignfile+reset) dann gehst Du in einer schleife durch die Datei. Findest Du einen zu löschenden record springst Du aus der Schleife heraus und öffnest die Datei, die immer noch offen ist erneut (assignfile+reset), das kann nicht gut gehen. Versuch doch zumindestens folgendes:
Delphi-Quellcode:
Das ist zwar nicht schön, sollte aber wenigstens fehlerfrei sein.
if key=Woerterbuch[i].Englisch then begin
... closefile(woert); {------- Datei schließen!!!!!! } löschen(h); exit; end Gruß K-H |
AW: Versuch hinter dem Dateiende zu lesen
Delphi-Quellcode:
SIeht mittlerweilse so aus sagt mir aber "Dateizugriff verweigert" und dannach habe ich angeblich eine Filesize von 1001 und es fehlen 2 Einträge.
procedure TForm1.Button5Click(Sender: TObject);
var key:String[25]; i:integer; h:integer; begin assignfile(woert,'Wörterbuch.dat'); Reset(woert); key:=Inputbox('Abfrage','Welches Wort löschen?(bitte das englische Wort eingeben)',''); for i := 1 to filesize(woert) do begin read(woert,Woerterbuch); if key=Woerterbuch[i].Englisch then begin h:=i; löschen(h); exit; end; showmessage('Das Wort steht nicht im Wörterbuch'); end; closefile(woert); end; Procedure löschen(h:integer); var m:Twoerterbuch2; begin Read(woert,Woerterbuch); while h<Filesize(woert) do begin m[h]:=Woerterbuch[h]; Woerterbuch[h]:=Woerterbuch[h+1]; Woerterbuch[h+1]:=m[h]; write(woert,Woerterbuch); inc(h); end; seek(woert,Filesize(woert)-1); truncate(woert); end; |
AW: Versuch hinter dem Dateiende zu lesen
Zitat:
Delphi-Quellcode:
bleibt noch das Closefile unterzubringen.
Procedure Loeschen(h:integer);
var tmpsatz : TMyWoertRec; maxidx : integer; begin maxidx:=filesize(woert); repeat seek(woert,h+1); read(woert,tmpsatz); dec(h,1); seek(woert,h); write(woert,tmpsatz); until h>=maxidx; truncate(woert); end; Hast Du einmal darüber nachgedacht, Deine Daten in einer TList unterzubringen? Das wäre auf jeden Fall schneller. Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:00 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