AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi wie kann ich bestimmte Infos aus Textdokument einlesen?
Thema durchsuchen
Ansicht
Themen-Optionen

wie kann ich bestimmte Infos aus Textdokument einlesen?

Ein Thema von Boyington · begonnen am 21. Mai 2012 · letzter Beitrag vom 6. Jun 2012
Antwort Antwort
Benutzerbild von Boyington
Boyington

Registriert seit: 12. Apr 2012
43 Beiträge
 
#1

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 4. Jun 2012, 23:08
Guten Abend Leute und danke für die Codes, Bummi.
Um Parameter "Dreiecke" (array of TDreieck) von dynamischem Array in Typ von "TList" umzuwandeln, habe ich original code von Klaus wie folgendes umgeschrieben:

Delphi-Quellcode:
type
   TVektor = record
     x, y, z: real;
   end;
   TDreieck = record
     n: TVektor; // n ist Normalvektor
     p: array[1..3] of TVektor; //p hat Koordinaten von 3 Eckpunkten
   end;
Var
   hDreieck:^TDreieck; //von mir zugefügt!!!
   //Dreiecke:Array of TDreieck;
   Dreiecke: TList; //von mir zugefügt!!!

PROCEDURE TMain.Test;
const
   recstart='facet normal';
   recline='vertex';
var list:TStrings; line:integer; data:TDreieck;

FUNCTION FindLine(const s:string; raiseerr:boolean):boolean;
begin
   while (line<list.count) and (Copy(Trim(list[line]),1,Length(s))<>s) do inc(line);
   if line<list.count then result:=true
      else if not raiseerr then result:=false
         else raise Exception.Create(s+' nicht gefunden.');
end;

FUNCTION ReadNumber(const s:string; var i:integer):real;
var j:integer;
begin
   j:=i;
   while s[j]<>' do dec(j);
   result:=StrToFloat(Copy(s,j+1,i-j));
   while s[j]=' do dec(j);
   i:=j;
end;

PROCEDURE ReadLine(var v:TVektor);
var s:string; i:integer;
begin
   s:=Trim(list[line]);
   i:=Length(s);
   v.z:=ReadNumber(s,i);
   v.y:=ReadNumber(s,i);
   v.x:=ReadNumber(s,i);
   inc(line);
end;

PROCEDURE ReadRecord;
var i:integer;
begin
   //ReadLine(data.n);
   ReadLine(hDreieck^.n); //von mir zugefügt!!!
   for i:=1 to 3 do begin
      FindLine(recline,true);
      //ReadLine(data.p[i]);
      ReadLine(hDreieck^.p[i]); //von mir zugefügt!!!
   end;
   //SetLength(Dreiecke,Length(Dreiecke)+1);
   //Dreiecke[High(dreiecke)]:=data;
   Dreiecke.Add(hDreieck); //von mir zugefügt!!!
end;

// var f:TextFile; i,j:integer; // nur zur Kontrolle benutzt
begin
   //Dreiecke:=nil; //von mir gelöscht
   list:=TStringList.Create;
   try
      try
         list.text:=Clipboard.AsText;
         // oder List.LoadFromFile('Filename');
         line:=0;
         while FindLine(recstart,false) do ReadRecord;
      except
         On E:Exception do begin
            ShowMessage(E.Message);
            //Dreiecke:=nil; //von mir gelöscht
         end;
      end;
   finally
      list.free;
   end;
end;
Ich bin nicht sicher, ob das Programm richtig ist, und evtl. s.g "Memory Leaks" vorhanden ist, weil the Codes der Ausgabe in Log.txt ich noch nicht umgeschrieben habe und auch nicht probieren kann.

Ich bin sehr dankbar für weitere Hilfe und nützliche Hinweise

Gruss
Lee
Do the best job, leave the rest in the hands of God!

Geändert von Boyington ( 5. Jun 2012 um 05:33 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.111 Beiträge
 
Delphi XE2 Professional
 
#2

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 5. Jun 2012, 00:36
Hallo Lee,
hast du schon mal probiert, das laufen zu lassen ?

Ich würde mal vermuten, dass in der Zeile v.z:=ReadNumber(s,i); in der Prozedur ReadLine eine Exception (Access Violation) kommt.

Warum?:
hDreieck ist ein Zeiger auf TDreieck und er ist = Nil, zeigt also ins Nichts.
Ins "Nichts" kannst du aber keine Daten schreiben.
Abhilfe:
New(hDreieck) als erste Zeile in die Prozedur ReadRecord einfügen.

Dann wirst du in der Zeile Dreiecke.Add(hDreieck); in der Prozedur ReadRecord eine Exception Exception (Access Violation) kriegen.
Warum?!
Die TList Dreiecke existiert noch nicht.
Abhilfe:
Dreiecke:=TList.Create als erste Zeile in der Prozedur Test einfügen.

Und wenn du dann irgendwann Dreiecke nicht mehr brauchst musst du erstens für alle Einträge in Dreiecke ein Dispose machen und anschließend ein Dreiecke.Free.

Letzteres solltest auch im except Block in Test machen.

Alternativ kannst du es so machen, wie Bummi es vorschlug.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von Boyington
Boyington

Registriert seit: 12. Apr 2012
43 Beiträge
 
#3

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 5. Jun 2012, 10:40
Danke dafür, Klaus!
Ich hab gerade das Programm wieder korrigiert, und die Compile scheint in Ordnung zu sein, aber ohne Ausgabe in Log.txt kann ich nun leider nicht überprüfen, ob das Ergebnis richtig ist.

Memory freemachen (am Anfang des Programms unter Type "procedure FormDestroy(Sender: TObject);" zugefügt):
Delphi-Quellcode:
procedure TForm1.FormDestroy(Sender: TObject);
var hDreieck:^TDreieck;
    i:integer;
begin
  for i:= 0 to Dreiecke.Count-1 do
  begin
    hDreieck:=Dreiecke[i];
    Dispose(hDreieck);
  end;
  Dreiecke.Free;
end;

Die original Ausgabe-Code von dir hab ich auch umgeschrieben:
Delphi-Quellcode:
procedure AddVector(const v:TVektor);
type TxVector=Array[0..2] of real;
var s:string; i:integer;
begin
   for i:=0 to High(TxVector) do s:=s+ToStr(TxVector(v)[i]);
   list.Add(s);
end;

var i,j:integer;
begin
   list:=TStringList.Create;
   try
      try
         //if Length(Dreiecke)=0 then
         if Dreiecke.count=0 then //von mir umgeschrieben
            raise Exception.Create('Dreiecke ist leer.');
         //for i:=0 to High(Dreiecke) do //wie ist entsprechende Code für TList???
            //with Dreiecke[i] do begin //record,objetc or class type required
               AddVector(n);
               for j:=Low(p) to High(p) do AddVector(p[j]);
               list.Add('');
            end;
         if tofile then list.SaveToFile(ExtractFilePath(ParamStr(0))+'Log.txt');
            //else Clipboard.AsText:=List.Text;
         ShowMessage('fertig.');
      except
         On E:Exception do ShowMessage(E.Message);
      end;
   finally
      list.free;
   end;
end;
Do the best job, leave the rest in the hands of God!
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.111 Beiträge
 
Delphi XE2 Professional
 
#4

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 5. Jun 2012, 17:57
Hallo Lee,

zu for i:=0 to High(Dreiecke) do //wie ist entsprechende Code für TList???
Ich bin sicher, dass du das auch ohne Hilfe herausbekommst.
Schau doch mal, wie du das in deinem "FormDestroy" machst.


Zu with Dreiecke[i] do begin //record,objetc or class type required
Die Fehlermeldung sagt doch was fehlt.
Erwartet wird ein Rekord-, Objekt- oder Klassentyp, Dreiecke[i] ist keines davon sondern ein Zeiger auf ein TDreieck. Wenn ich das richtig sehe, ist das dem Compiler aber nicht bekannt, für den ist Dreiecke[i] nur ein Zeiger auf einen Speicherbereich.
Wenn du schreibst with hDreieck(Dreiecke[i]) do begin dann weiß er zumindest, dass es sich um einen Zeiger auf ein TDreieck handelt, was aber das Problem nicht heilt, denn es wird ja ein Rekord-, Objekt- oder Klassentyp erwartet.
Mit with hDreieck(Dreiecke[i])^ do begin sollte es funktionieren (Beachte das ' ^ ').
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von Boyington
Boyington

Registriert seit: 12. Apr 2012
43 Beiträge
 
#5

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 5. Jun 2012, 21:13
Hallo Lee,

zu for i:=0 to High(Dreiecke) do //wie ist entsprechende Code für TList???
Ich bin sicher, dass du das auch ohne Hilfe herausbekommst.
Schau doch mal, wie du das in deinem "FormDestroy" machst.


Zu with Dreiecke[i] do begin //record,objetc or class type required
Die Fehlermeldung sagt doch was fehlt.
Erwartet wird ein Rekord-, Objekt- oder Klassentyp, Dreiecke[i] ist keines davon sondern ein Zeiger auf ein TDreieck. Wenn ich das richtig sehe, ist das dem Compiler aber nicht bekannt, für den ist Dreiecke[i] nur ein Zeiger auf einen Speicherbereich.
Wenn du schreibst with hDreieck(Dreiecke[i]) do begin dann weiß er zumindest, dass es sich um einen Zeiger auf ein TDreieck handelt, was aber das Problem nicht heilt, denn es wird ja ein Rekord-, Objekt- oder Klassentyp erwartet.
Mit with hDreieck(Dreiecke[i])^ do begin sollte es funktionieren (Beachte das ' ^ ').
Abend Klaus, danke für deine nette und ausführliche Erklärung!
zu 1). Da hast du recht "for i:=0 to High(Dreiecke) do" soll durch "for i:=0 to Dreiecke.Count-1 do" ersetzt werden, ich hab es in "FormDestroy" schon gemacht, bin doch blöd

zu 2). "with hDreieck(Dreiecke[i])^ do begin" schon in Programm geschrieben, aber leider hab ich wieder Fehlermeldung bekommen: Missing Operator or semicolon

Meine Frage: es ist ganz klar, dass Dreiecke[i] ein Zeiger auf ein TDreieck ist. Aber was ist denn hDreieck(Dreiecke[i])? Also hDreieck(ein Zeiger auf ein TDreieck ) ist auch ein Zeiger auf ein TDreieck? Ich bin verwirrt.

Gruss
Lee
Do the best job, leave the rest in the hands of God!

Geändert von Boyington ( 5. Jun 2012 um 21:18 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.111 Beiträge
 
Delphi XE2 Professional
 
#6

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 6. Jun 2012, 02:19
Hallo Lee,

tja, dann fehlt da vielleicht irgendwo ein Semikolon.

Ich habe das mal getestet mit nachstehender Prozedur.
Wundere dich nicht, dass die auch Test heißt. (Bei mir gibt es in jedem Projekt eine Prozedur "Test" (zum Testen, wie der Name sagt.)).

Zu
Meine Frage: es ist ganz klar, dass Dreiecke[i] ein Zeiger auf ein TDreieck ist. Aber was ist denn hDreieck(Dreiecke[i])? Also hDreieck(ein Zeiger auf ein TDreieck ) ist auch ein Zeiger auf ein TDreieck? Ich bin verwirrt.

Nein, es ist eben nicht ganz klar, dass Dreiecke[i] ein Zeiger auf ein TDreieck ist.
Das weißt du, nicht aber der Compiler, denn TList ist einfach nur eine Liste mit Pointern.
Dadurch dass du die TList "Dreiecke" nennst, wird Dreiecke[i] für den Compiler nicht zu einem Zeiger auf ein TDreieck.
Erst durch hDreieck(Dreiecke[i]) wird der Pointer zu einem Pointer auf ein TDreieck.
Und mit dem ' ^ ' dahinter 'weiß' der Compiler, dass er auf einen Record TDreieck zugreifen soll.

OT : Wenn du die Variable "Dreiecke" umbenennst in "Kirchturmuhr" wird daraus ja auch kein Zeiger einer Uhr.

Delphi-Quellcode:
type
   TVektor = record
      x, y, z: real;
   end;
   TDreieck = record
      n: TVektor; // n ist Normalvektor
      p: array[1..3] of TVektor; //p hat Koordinaten von 3 Eckpunkten
   end;
   hDreieck=^TDreieck;

var
   Dreiecke:TList;

PROCEDURE TMain.Test;
var i,j:integer; pDreieck:hDreieck; list:TStrings; s:string;
begin
   Dreiecke:=TList.Create;
   for i:=1 to 3 do begin
      New(pDreieck);
      pDreieck.n.x:=i*100+1;
      pDreieck.n.y:=i*100+2;
      pDreieck.n.z:=i*100+3;
      for j:=1 to 3 do begin
         pDreieck.p[j].x:=i*100+j*10+1;
         pDreieck.p[j].y:=i*100+j*10+2;
         pDreieck.p[j].z:=i*100+j*10+3;
      end;
      Dreiecke.Add(pDreieck);
   end;
   list:=TStringList.Create;
   for i:=0 to Dreiecke.Count-1 do
      with hDreieck(Dreiecke[i])^ do begin
         list.Add('n '+
                  FloatToStr(n.x)+' '+FloatToStr(n.y)+' '+FloatToStr(n.z));
         for j:=1 to 3 do
            list.Add('p['+IntToStr(j)+'] : '+
                     FloatToStr(p[j].x)+' '+FloatToStr(p[j].y)+' '+FloatToStr(p[j].z));
         list.Add('');
      end;
   list.SaveToFile('Log.txt');
   list.Free;
   for i:=0 to Dreiecke.Count-1 do Dispose(Dreiecke[i]);
   Dreiecke.Free;
end;
Das Ergebis in Log.txt :
Code:
n     101 102 103
p[1] : 111 112 113
p[2] : 121 122 123
p[3] : 131 132 133

n     201 202 203
p[1] : 211 212 213
p[2] : 221 222 223
p[3] : 231 232 233

n     301 302 303
p[1] : 311 312 313
p[2] : 321 322 323
p[3] : 331 332 333
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.667 Beiträge
 
Delphi 12 Athens
 
#7

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 6. Jun 2012, 07:14
Der Vorteil von TList ist die Flexibilität, da sie untypisierte Pointer enthält. Der Nachteil ist ihre Flexibilität, da sie nur untypisierte Pointer enthält . Um ein Mindestmaß an Typsicherheit zu erreichen, könnte man eine eigene Liste von TList ableiten, die dann nur typsierte Pointer eines bestimmten Typs verarbeitet, in aktuellen Delphi-Versionen auf eine generische Liste umsteigen, oder aus den Records Klassen machen und in einer TObjecList verwalten, dann hat man zumindest die Möglichkeit, die Einträge mittels is und as auf ihren Typ zu untersuchen (oder man leitet auch hier wieder eine spezialisierte Liste ab).
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:52 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