![]() |
Record in Datei speichern
Hallo
Ich habe folgendes Problem. Möchte gerne diese Programm zum laufen bekommen. Es soll eine Datei erstelle wo die Daten aufgelistet sind. Irgendwo ist hier aber wieder ein Fehler. Er bleibt immer beim TZielFile = file of TZiel; stehen Das ganze soll auf drücken eines Buttons geschehen. Den habe ich ZielErfassen als Name gegeben
Delphi-Quellcode:
unit Unit1;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs; type { TForm1 } TForm1 = class(TForm) procedure Button1Click(Sender: TObject); private { private declarations } public { public declarations } end; type TZiel = record Ort: String; Preis: real; end; type TZielliste = record Ziele: array[1..100] of TZiel; ZielZahl: integer; end; TZielFile = File of TZiel; var Form1: TForm1; ZielListe: TZielliste; Zielfile: TZielFile; I: integer; implementation {$R *.lfm} { TForm1 } procedure ZieleErfassen(var Liste: TZielListe); begin with Liste do begin Ziele[1].Ort:='Dresden'; Ziele[1].Preis:=16.00; with Ziele[2] do begin Ort := 'Berlin'; Preis := 43.00; end; with Ziele[3] do begin Ort :='Aachen'; Preis := 155.00; end; ZielZahl :=3; end; end; ZieleErfassen(ZielListe); Assign(Zielfile, 'C:\Users\Notebook\Desktop\ziele.dat'); Rewrite(Zielfile); with ZielListe do for I := 1 to ZielZahl do write(ZielFile, Ziele[I]); Close(ZielFile); end; end. |
AW: Record in Datei speichern
Ort als String kann hierfür nicht verwendet werden, da die Länge nicht fix ist
Ort: String[100] z.B. ginge |
AW: Record in Datei speichern
Hallo
Ja das hat jetzt schon weiter geholfen. Mir ist aber geradea aufgefallen das mein Button gar nicht im Namen geändert ist da gibts immer nen Fehler... Jetzt bin ich wieder ratlos? was muss ich denn machen damit das halt einfach auf Knopfdruck das jetzt speichert? |
AW: Record in Datei speichern
Einmal "type" genügt, solange keine andere Deklaration dazwischen erfolgt. Die Laufvariable I muss eine lokale Variable sein, und ändere mal Assign in AssignFile und Close in CloseFile. Außerdem hast Du wohl 2 "end" zuviel, rück mal korrekt ein, dann siehst Du auch, wo.
|
AW: Record in Datei speichern
Ich sehe keinen Button auf dem Formular. Damit sollte man am besten anfangen ;) (Obwohl du einen Event-Handler für einen ButtonClick da stehen hast. Das schaut seltsam aus. Hast du das von Hand da hin geschrieben?)
|
AW: Record in Datei speichern
So hab nen paar Sachen geändert
Jetzt hab ich ein Problem mit Listen? Ich hab das auch noch nicht so verstanden wieso bei der procedure in der Vorgabe das mit (var Liste: TZielListe); drinne steht?
Delphi-Quellcode:
unit Unit1;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { private declarations } public { public declarations } end; TZiel = record Ort:String[20]; Preis: real; end; TZielListe = record Ziele: array[1..100] of TZiel; ZielZahl: integer; end; TZielFile = file of TZiel; var Form1: TForm1; ZielListe: TZielListe; ZielFile: TZielFile; I: Integer; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); //procedure ZieleErfassen(var Liste: TZielListe); begin with Liste do begin Ziele[1].Ort:='Dresden'; Ziele[1].Preis:=16.00; end; with Ziele[2] do begin Ort := 'Berlin'; Preis := 43.00; end; with Ziele[3] do begin Ort :='Aachen'; Preis := 155.00; end; ZielZahl :=3; ZieleErfassen(ZielListe); Assign(Zielfile, 'C:\Notebook\Desktop\ziele.dat'); Rewrite(Zielfile); with ZielListe do for I := 1 to ZielZahl do begin write(ZielFile, Ziele[I]); Close(ZielFile); end; end; end. |
AW: Record in Datei speichern
Vermutlich, weil Du eine eigene Prozedur "ZieleErfassen" schreiben sollst, die die übergebene Liste befüllen soll.
|
AW: Record in Datei speichern
Delphi-Quellcode:
procedure ChangeValue(var Value: integer);
begin Value := 10; end; procedure NotChangeValue(Value: integer); begin Value := 10; end; procedure TForm1.Button2Click(Sender: TObject); var I: integer; begin I:= 1; NotChangeValue(I); ShowMessage(IntToStr(I)); ChangeValue(I); ShowMessage(IntToStr(I)); end; |
AW: Record in Datei speichern
ah genau das hab ich gerade verstanden was mit dieser Procedur da gemeint ist.
Aber die Procedur an sich geht schon nicht. Da kommen Fehler: Identifier not found "Ziele" Expression type must be class or record type ... ... Fehlt da irgendwie noch eine deklaration? |
AW: Record in Datei speichern
Versuch mal folgendes
Delphi-Quellcode:
Gruß
procedure TForm1.Button1Click(Sender: TObject);
begin with ZielListe do begin with Ziele[1] do begin Ort:='Dresden'; Preis:=16.00; end; with Ziele[2] do begin Ort := 'Berlin'; Preis := 43.00; end; with Ziele[3] do begin Ort :='Aachen'; Preis := 155.00; end; ZielZahl :=3; end; Assign(Zielfile, 'C:\Notebook\Desktop\ziele.dat'); Rewrite(Zielfile); with ZielListe do for I := 1 to ZielZahl do write(ZielFile, Ziele[I]); Close(ZielFile); end; |
AW: Record in Datei speichern
So die Procedure geht jetzt da passte die end nicht ganz
So jetzt geht aber das nicht mit dem Button? Ich hab das Gefühl das da eine Variable unter button1 fehlt? Oder was mach ich jetzt wieder falsch? Fehler sind: unit1.pas(81,3) Error: Wrong number of parameters specified for call to "ZieleErfassen" unit1.pas(49,11) Hint: Found declaration: ZieleErfassen(var TZielListe); unit1.pas(85) Fatal: There were 1 errors compiling module, stopping
Delphi-Quellcode:
unit Unit1;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { private declarations } public { public declarations } end; TZiel = record Ort:String[20]; Preis: real; end; TZielListe = record Ziele: array[1..100] of TZiel; ZielZahl: integer; end; TZielFile = file of TZiel; var Form1: TForm1; ZielListe: TZielListe; ZielFile: TZielFile; I: Integer; implementation {$R *.lfm} { TForm1 } procedure ZieleErfassen(var Liste: TZielListe); begin with Liste do begin Ziele[1].Ort:='Dresden'; Ziele[1].Preis:=16.00; with Ziele[2] do begin Ort := 'Berlin'; Preis := 43.00; end; with Ziele[3] do begin Ort :='Aachen'; Preis := 155.00; end; ZielZahl :=3; end; ZieleErfassen(ZielListe); Assign(Zielfile, 'C:\Users\Desktop\adress.dat'); Rewrite(Zielfile); with ZielListe do for I := 1 to ZielZahl do begin write(ZielFile, Ziele[I]); Close(ZielFile); end; end; procedure TForm1.Button1Click(Sender: TObject); begin ZieleErfassen; end; end. |
AW: Record in Datei speichern
Zitat:
Zitat:
Delphi-Quellcode:
ZieleErfassen (ZielListe);
Dann wird die procedure ZieleErfassen in der procedure selbst nochmals aufgerufen, was dann zu einem Stackowerflow führen wird. Und Du solltest noch das CloseFile(); aus der for-Schleifen nehmen! Gruß |
AW: Record in Datei speichern
So der Compiler läuft jetzt durch
Beim klicken des Buttons kommt nun ein Fenster Projekt projekt1 hat Exception-Klasse>>External: SIGSEGV<< ausgelöst. In Datei'unit1.pas' in Zeile 50: begin Das ist nach der procedure Zieleerfassen
Delphi-Quellcode:
unit Unit1;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { private declarations } public { public declarations } end; TZiel = record Ort:String[20]; Preis: real; end; TZielListe = record Ziele: array[1..100] of TZiel; ZielZahl: integer; end; TZielFile = file of TZiel; var Form1: TForm1; ZielListe: TZielListe; ZielFile: TZielFile; I: Integer; implementation {$R *.lfm} { TForm1 } procedure ZieleErfassen(var Liste: TZielListe); begin with Liste do begin Ziele[1].Ort:='Dresden'; Ziele[1].Preis:=16.00; with Ziele[2] do begin Ort := 'Berlin'; Preis := 43.00; end; with Ziele[3] do begin Ort :='Aachen'; Preis := 155.00; end; ZielZahl :=3; end; ZieleErfassen(ZielListe); Assign(Zielfile, 'C:\Users\Desktop\adress.dat'); Rewrite(Zielfile); with ZielListe do for I := 1 to ZielZahl do begin write(ZielFile, Ziele[I]); end; Close(ZielFile); end; procedure TForm1.Button1Click(Sender: TObject); var Zielliste:TZielliste; begin ZieleErfassen(Zielliste); end; end. |
AW: Record in Datei speichern
Zitat:
Gruß |
AW: Record in Datei speichern
Du produzierst eine Stackoverflow. Schmeiß das ZieleErfassen(ZielListe) in ZieleErfassen raus. Und die überflüssigen Variablen gleich mit. :-D Und das with auch, wurde dir schon gesagt, ist schlechter Stil.
|
AW: Record in Datei speichern
Habe ich vorhin noch übersehen: Der zweite with-Block kann mit "ZielListe" nichts anfangen, wenn dann muss es schon
Delphi-Quellcode:
heißen.
[B]with[/B] Liste [B]do[/B]
Gruß |
AW: Record in Datei speichern
ah sehr gut danke euch
jetzt geht es. Mhh jetzt sieht die Datei aber so aus: DresdenðÊÙ4ê†àÙ0è 0@Berlin*Š X:Ýìé €E@AachenÔ:Ý „ê `c@ ist das richtig? müsste das nicht Dresden 16.00 Berlin 43.00 Aachen 155.00 aussehen? was muss ich denn machen damit das wieder so wird? |
AW: Record in Datei speichern
Wieso wirfst Du das with nicht raus? Wie Du siehst, stiftet es nur Verwirrung. Aber AssignFile und CloseFile sehe ich ja auch noch nicht, was soll's also :?
|
AW: Record in Datei speichern
ich weiß nicht genau welche with du meinst?
Das mit dem Assignfile, closefile habe ich gerade geändert |
AW: Record in Datei speichern
Na, alle with.
Delphi-Quellcode:
So siehst Du doch gleich, was passiert und musst nicht überlegen, in welchem with Du gerade bist.
procedure ZieleErfassen(var Liste: TZielListe);
begin Liste.Ziele[1].Ort:='Dresden'; Liste.Ziele[1].Preis:=16.00; Liste.Ziele[2].Ort := 'Berlin'; Liste.Ziele[2].Preis := 43.00; Liste.Ziele[3].Ort :='Aachen'; Liste.Ziele[3].Preis := 155.00; ZielZahl := 3; end; |
AW: Record in Datei speichern
Ok das sieht besser aus.
Aber wie schon geschrieben der wunsch ist das wir das mit diesem with lösen sollen weil das ja jetzt ,,neu" ist bei uns. Aber was ist mit der Datei? Wie bekomme ich das hin das alles als lesbare Daten da drinne steht? |
AW: Record in Datei speichern
Wie jetzt? Eine typisierte Datei, die man mal eben im Editor anschauen kann? Wie soll das gehen, wenn man außer Strings noch andere Datentypen verwenden will?
|
AW: Record in Datei speichern
Jedes with !!
und wenn Deine Daten so kryptisch ausschauen, dann liegt das daran, daß Du ein Record mit z.B. dem "preis" der eine real-Zahl ist, speicherst. Was Du erwartest ist das Ergebnis der Umwandlung Floattostring, das ist dann ein String und keine real-Zahl mehr. Gruß K-H Oh zu spät.... Wie wäre es denn wenn Du einmal genau definierst was Du (oder Dein Lehrer) willst? |
AW: Record in Datei speichern
Mhh das stimmt das macht ja nicht viel Sinn
|
AW: Record in Datei speichern
Ohne daß ich sah, daß Du tatsächlich einen neuen Thread dazu aufgemacht hast, hatte ich Dir
![]() Ich weiß gar nicht, was DeddyH inmmer gegen "with" hat ! Sinnvoll angewandt, erleichtert es die Arbeit enorm. |
AW: Record in Datei speichern
Zitat:
Angenommen Du oder Emba kommen auf die Idee, z. B. eine Klasse um eine Methode oder property zu erweitern, dann kann es bei with zu sehr unangenehmen Konflikten kommen. Solche Fehler zu finden dauert meist Stunden. Beispiel:
Delphi-Quellcode:
type
TRecord = record A, B, C, D, E, F, G, H, I(Neu): integer; end; procedure DoSomeThing; var ARecord : TRecord; I : integer; begin with ARecord do begin // for I:= 1 to 10 do I:= 1; .. end; end; |
AW: Record in Datei speichern
Für ein With, schlimmer noch, wenn mehrere withs geschachtelt werden, muß man immer im Hinterkopf behalten worauf with sich bezieht. Ist alles ausformuliert, gibt es da kein Vertun.
Gruß K-H |
AW: Record in Datei speichern
Und das debuggen macht man sich dadurch auch nur komplizierter.
|
AW: Record in Datei speichern
Nicht grundlos schrieb ich "Sinnvoll angewandt" ! Bei komplexen Strukturen würde ich das nie machen und wahrscheinlich sogar eher was in Unterprozeduren auslagern. Wenn man sich aber z.B. auf eine Komponente bezieht und dann beispielsweise schreibt "with StringGrid do begin" gibt das mehr Sinn, als jedesmal "StringGrid" davor zu schreiben. Vor allem bei vollständig gekapselten, kompakten Methoden ...
Aber jeder wie er mag und es ihm sinnvoll scheint. Mich hat eigentlich eher gestört, daß jemand einem anderen indirekt Vorschriften machen will, nur weil ihm selbst was mißfällt. Solange etwas programmiertechnisch umsetzbar ist, sind selbst die umständlichsten Methoden zielführend. Wirklich von Interesse sollte für uns doch letztlich nur sein, was schneller zum Erfolg führt. Wer umständlich programmiert und dann Vorschläge für kürzere unmd übersichtlichere Lösunmgsansätze findet, wird immer dafür dankbar sein. Auch wenn das nicht ganz hierher gehört : Mit Schrecken denke ich gerade an die Leute, die sich über lange Assembler-Quelltexte aufgeregt haben und sich dann wunderten, daß ihre absurden Quelltexte aus C-Abarten im Gegensatz zu reinen Assembler-Lösungen extrem aufgeblähte EXE-Dateien ergaben. Ich vergleiche das jetzt einfach mal mit den aufgeblähten Ergebnissen, die das unflexible Lazarus zuwege bringt - so daß ich lieber bei meinem bewährten Delphi 5 blieb. (Aktuelle Delphi-Versionene sind mir einfach zu teuer.) Nachtrag : Wer seine Quelltexte nicht ausreichend kommentiert, kann natürlich leicht Schwierigkeiten bei der Fehlersuche bekommen. Gegliederte Strukturen kommentiere ich z.B. so :
Delphi-Quellcode:
// procedure xy procedure xy; var ... begin { Procedure xy } with bla do begin // with bla end; // with bla end; { Procedure xy } // nächste Prozedur oder was auch immer ... |
AW: Record in Datei speichern
Zitat:
Zitat:
Wenn Du mit "schneller" meinst, daß der Code schneller geschrieben ist, dann solltest Du auch dazu übergehen, Dir Kommentare zu verkneifen. Ebenso spricht dann nichts gegen Bandwurmzeilen, die mehrere Anweisungen enthalten. Ein gutes neues Jahr K-H |
AW: Record in Datei speichern
Ich denke nicht, daß ich da empfindlich reagiere, denn mich berührt das nur am Rande. Mir fiel unangenehm auf, daß ein Neuling, der dieses "with" offensichtlich benutzen soll, dafür kritisiert wird. Meine Quellcodes sind meist so geschrieben, daß ich derartige Konstrukte auf andere Weise löse, so daß sich die Frage ob mit oder ohne "width" oft gar nicht stellt.
Schnelles Schreiben von Quellcode meinte ich nicht, sondern die Ausführung der EXE-Datei. Aus meiner Bemerkung bzgl. Leuten, die mit C-Abkömmlingen programmier(t)en, sollte das eigentlich hervorgehen. Entscheidend sollte sein, welcher Code sich als am Zweckmässigsten erweist. Das meinte ich mit "schneller zum Erfolg führt". Vernünftige Kommentare an den richtigen Stellen würde ich nie vernachlässigen. Vor allem dann, wenn man seine Quellen auch anderen verfügbar machen will - egal ob mit oder ohne "width". Die Diskussionen darüber sind so wenig sinnvoll wie überhaupt Kritik am Programmierstil anderer. Wer andere Wege kennt, sollte diese ohne Spott als Alternative vorstellen. Damit hoffe ich, diese abwegige Diskussion beendet zu haben. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:26 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 by Thomas Breitkreuz