Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Fehlersuche... (https://www.delphipraxis.net/1110-fehlersuche.html)

andi_hauser 19. Okt 2002 00:17


Fehlersuche...
 
Liste der Anhänge anzeigen (Anzahl: 1)
type
CDrec = record
name,pos,komment:shortstring;
maxentry,nr:integer;
entry:array[1..24] of shortstring;
end;
[...]

var
datei:file of CDrec;
dateiMAX:file of integer;

[...]

write(datei,CD[number]); :oops: Hier hängt der Compiler fest und melden einen EinOtError / dateizugriff verweigert! obwohl CD[number] zuvor mit allen record-Daten gefüttern wurde... :oops:

CD[number].Nr:=StrToInt(Edit[25].text);
CD[number].name:=Edit[26].text;
CD[number].pos:=Edit[27].text;
CD[number].maxentry:=StrToInt(Edit[28].text);
CD[number].komment:=Edit[29].text;
for i:=1 to CD[number].maxentry do
CD[number].entry[i]:=Edit[i].text;


Wer kann mir helfen?

thomasdrewermann 19. Okt 2002 00:26

Warum übergibst du deiner Procedure
Code:
procedure Save2Registry(number:integer);
nicht einfach eine Variabele mit dem Typ CD?

dann brauchste garkein array in der Procedure.

Wenn du es so machen möchstes, wie du es angefangen hast, dann versuchs mal mit:

Ergänze unter der Deklaration der Elemente auf dem Form deine Procedure:
Code:
procedure FormCreate(Sender: TObject);
    procedure Edit6Change(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Save2Registry(number:integer);
Dann schreibste unten bei deiner Procedure nicht
Code:
procedure Save2Registry(number:integer);
sondern
Code:
procedure TForm1.Save2Registry(number:integer);
dann sollte es funzen.

Ich hoffe es zu mindest.

thomasdrewermann 19. Okt 2002 00:29

Ich denke ausserdem, dass du keine Daten vom Typ CD in die Datei schreiben kannst, sondern nur daten vom Typ String. oder?

MathiasSimmack 19. Okt 2002 08:10

Zitat:

Ich denke ausserdem, dass du keine Daten vom Typ CD in die Datei schreiben kannst, sondern nur daten vom Typ String
Falsch gedacht. Die Datei ist ja schließlich als
Code:
file of CDrec
deklariert. Und dass es neben Textdateien auch noch andere (binäre) Formate gibt, müsstest du eigentlich wissen. Und, warum sollte man mit Delphi solche Sachen also nicht auch machen können?

Ich habe früher aber nur "blockread/blockwrite" benutzt und die Datei ganz simpel nur als
Code:
file
deklariert. Das hat bei meinen Versuchen immer tadellos funktioniert. Aber mit "write" sollte es bei einer typisierten Datei -s. Andys Deklaration- eigentlich auch gehen.

Meine Frage wg. des Fehlers wäre: wie hast du die Datei geöffnet, Andy? Ich sehe in deinem Quellcode zwar die "write"-Anweisung, aber der Teil davor (AssignFile ff.; oder was immer du benutzt) fehlt. Das wäre aber ein Anhaltspunkt um dir zu helfen.
Möglich, dass die Datei auch noch durch einen anderen Teil deines Programms belegt wird?

Dein geposteter Code ist zu kurz, um ´ne vernünftige Aussage treffen zu können.

Generell würde ich aber den verwendeten Strings im Record eine Länge zuordnen:
Code:
name,pos,komment:string[50];
...
entry:array[1..24] of string[70];
Da ein ShortString ja bis 255 Zeichen lang sein kann, musst du die absolute Länge festlegen, damit die gespeicherten Records in der Datei immer gleich lang sind. Sonst gibt´s u.U. Probleme mit dem Suchen eines Records (anhand der Recordlänge) und mit dem Einlesen natürlich.
Und du bist sicher, dass "entry" wirklich ein Array von 70 Strings sein soll? Ah, das wird die Titelliste sein ... :idea:

MathiasSimmack 19. Okt 2002 09:12

So, ausgehend von folgendem Record:
Code:
type
  CDrec = record
    name,
    pos,
    comment : string[50];
    maxentry,
    nr      : integer;
    entry   : array[1..24]of string[70];
  end;
habe ich zuerst einen einfachen Versuch gestartet:
Code:
var
  CD : CDrec =
    (name:'Brandenburg Concertos 1 - 3';
     pos:'1'; // mangels besseres Wissen habe ich ´ne Eins benutzt
     comment:'Johann Sebastian Bach';
     maxentry:9;
     nr:1; // auch hier habe ich keine Ahnung, was dies ist
     entry:('Allegro',
      'Adagio',
      'Allegro',
      'Menuetto-Trio-Polacca',
      'Allegro',
      'Andante',
      'Allegro assai',
      'Allegro',
      'Allegro', // das Stück ist das bekannteste, IMHO :o)
      '','','','','','','','','','','','','','',''));

procedure TForm1.SaveSimpleClick(Sender: TObject);
var
  datei : file of CDrec;
begin
  {$I-}
  AssignFile(datei,'bc1-3.cd');
  ReWrite(datei);
  Write(datei,CD);
  CloseFile(datei);
  {$I+}
end;
Ergebnis: Null Fehler, Datei "bc1-3.cd" ist mit 1,82k vorhanden.

Und nun die Variante, bei der ich das CD-Record seinerseits in ein Array gepackt habe, wobei ich mich aber auf 2 Arrayfelder beschränkt und das zweite auch leergelassen habe:
Code:
var
  CDarray : array[1..2]of CDrec = (   // wir wollen ma´ nich´ übertreiben
    (name:'Brandenburg Concertos 4 - 6';
     pos:'1';
     comment:'Johann Sebastian Bach';
     maxentry:9;
     nr:1;
     entry:('Allegro',
      'Andante',
      'Presto',
      'Allegro',
      'Affetuoso',
      'Allegro',
      'Allegro',
      'Adagio ma non tanto',
      'Allegro',
      '','','','','','','','','','','','','','','')),
    // und ein leeres
    (name:'';
     pos:'';
     comment:'';
     maxentry:0;
     nr:0;
     entry:('','','','','','','','','','',
       '','','','','','','','','','',
       '','','','')));

procedure TForm1.SaveAsRecordClick(Sender: TObject);
var
  datei : file of CDrec;
begin
  {$I-}
  AssignFile(datei,'bc4-6.cd');
  ReWrite(datei);
  Write(datei,CDarray[2]); // <-- das leere zuerst!
  Write(datei,CDarray[1]);
  CloseFile(datei);
  {$I+}
end;
Ergebnis: Null Fehler, Datei "bc4-6.cd" hat naturgemäß die doppelte Größe, weil ich beide Arrays gespeichert habe.

Und nun zum Einlesen der zuletzt gespeicherten Datei:
Code:
procedure TForm1.GetItClick(Sender: TObject);
var
  datei : file of CDrec;
  mycd : CDrec;
begin
  {$I-}
  AssignFile(datei,'bc4-6.cd');
  Reset(datei);
  while(not(eof(datei))) do
    begin
      Read(datei,mycd);

      ShowMessage(mycd.name + #13#10 +
        mycd.comment);
    end;
  CloseFile(datei);
  {$I+}
end;
Beim ersten Mal wird logischerweise nichts zurückgeliefert, weil ich das leere Array ja auch gespeichert habe. Beim zweiten Durchlauf sollte aber der JSB erscheinen, und dann ist die Datei auch schon zu Ende.

Damit habe ich mal wieder meine Bürgerpflicht erfüllt und kann wohl ins Wochenende gehen? 8)

<-------------->

PS: Eins fehlt ja noch; das Ändern -
Also, ich habe als neue Datei "bc1-6.cd" mit allen drei CD-Records erzeugt:
Code:
  {$I-}
  AssignFile(datei,'bc1-6.cd');
  ReWrite(datei);

  Write(datei,CD);
  Write(datei,CDarray[2]); // <-- das leere in der Mitte
  Write(datei,CDarray[1]);

  CloseFile(datei);
  {$I+}
Und dann ergänze ich einfach mal den Titel #24 im ersten Record:
Code:
procedure TForm1.ChangeClick(Sender: TObject);
var
  datei : file of CDrec;
  mycd : CDrec;
  fp   : longint;
begin
  {$I-}
  AssignFile(datei,'bc1-6.cd');
  Reset(datei);
  while(not(eof(datei))) do
    begin
      // Position des aktuellen Feldes
      fp := filepos(datei);

      // Feld lesen
      Read(datei,mycd);

      if(CompareText('Brandenburg Concertos 1 - 3',mycd.name) = 0) then
        begin
          // eindeutige Copyright-Verletzung :o)
          mycd.entry[24] := 'Mondschein-Sonate in C#m';

          // zum Anfang des Feldes zurück
          Seek(datei,fp);

          // und schreiben
          Write(datei,mycd);
        end;
    end;
  CloseFile(datei);
  {$I+}
end;
Jetzt is´ aber Schluss. :)

Christian Seehase 19. Okt 2002 12:59

Moin Mathias,

Nur als Ergänzung:
Ausgehend davon, dass das Feld entry den Titeln auf der CD entspricht, wäre es dann allerdings ganz sinnvoll, dieses von 1 bis 99 zu deklarieren, da, wenn ich nicht sehr irre, gemäss Audio CD Standard bis zu 99 Tracks erlaubt sind.
Das wird zwar in der Masse der Fälle nicht annähnernd ausgeschöpft werden, kann aber vorkommen.

MathiasSimmack 19. Okt 2002 15:31

Du irrst natürlich nicht, Christian. Es sind 99 Titel möglich, aber das muss Andi dann wissen. Vielleicht reichen ihm ja 24 Einträge; vielleicht ist´s auch gar nicht die Titelliste ...

btw: von den "Nine Inch Nails" gibt´s die CD "broken". Da sind 99 Titel drauf, allerdings sind die Tracks #6 bis #97 leer. :wink: Interessant in dem Zusammenhang ist vielleicht, dass diese CD in meinem Schrank witzigerweise neben der o.g. 3er-CD von Bach steht ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:17 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