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
Seite 1 von 4  1 23     Letzte »    
Benutzerbild von Boyington
Boyington

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

wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 21. Mai 2012, 20:54
Hallo Leute,
weiß Jemand vielleicht, wie ich alle Koordinaten aus einem Textdokument (*.stl Datei im ASCII Format) einlesen und dann in einer Liste speichern kann? Da ich mich mit Text- oder StringVerarbeitung in Delphi nicht gut auskenne.

*.stl Datei (ASCII Format) sieht wie folgendes aus:

Code:
solid ascii
  facet normal 2.445222e-016 0.000000e+000 1.000000e+000
    outer loop
      vertex  -2.007874e+000 1.968504e+000 5.905512e-002
      vertex  -2.007874e+000 -1.968504e+000 5.905512e-002
      vertex  -1.574803e-001 -1.968504e+000 5.905512e-002
    endloop
  endfacet
  facet normal 2.445222e-016 -5.090141e-032 1.000000e+000
    outer loop
      vertex  -1.574803e-001 -1.968504e+000 5.905512e-002
      vertex  -1.574803e-001 1.968504e+000 5.905512e-002
      vertex  -2.007874e+000 1.968504e+000 5.905512e-002
    endloop
  endfacet
.
.
.
.
 facet normal 7.071068e-001 -1.471962e-016 7.071068e-001
    outer loop
      vertex  -1.574803e-001 1.968504e+000 5.905512e-002
      vertex  -1.574803e-001 -1.968504e+000 5.905512e-002
      vertex  -3.937008e-002 -1.968504e+000 -5.905512e-002
    endloop
  endfacet
endsolid
Jedes 3D-Objekt besteht aus vielen kleinen Dreiecken und jedes Dreieck besteht aus 1x normal (Nomalvektor) und 3x vertex (Koordinaten der 3 Eckpunkten von jedem Dreieck).

Meine Frage ist: wie kann ich vom Anfang bis zum Ende der *.stl Datei alle Normalvektoren (als type: TVektor) und alle Koordinaten der 3 Eckpunkten von jedem Dreieck in einer Liste speichern (die Liste soll dynamisch sein, weil die Länge der Liste vorher nicht bekannt ist)?

Typen sehen ungefähr wie folgendes aus:
Code:
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;
Ich bitte euch um die Hilfe und bin sehr dankbar für die Antwort wie immer

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

Geändert von Boyington (21. Mai 2012 um 21:03 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

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

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 21. Mai 2012, 23:44
Versuch es mal hiermit.
Ich habe die von dir gezeigten daten ins Clipboard kopiert
und von dort in die StringList geschrieben.
Alle Daten wurden korrekt gelesen.
Du solltest das mit list.LoadFromFile machen.
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;
   Dreiecke:Array of TDreieck;

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);
   for i:=1 to 3 do begin
      FindLine(recline,true);
      ReadLine(data.p[i]);
   end;
   SetLength(Dreiecke,Length(Dreiecke)+1);
   Dreiecke[High(dreiecke)]:=data;
end;
// var f:TextFile; i,j:integer; // nur zur Kontrolle benutzt
begin
   Dreiecke:=nil;
   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;
         end;
      end;
   finally
      list.free;
   end;
end;
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 22. Mai 2012, 07:34
Morgen alle,
vielen Dank für die nette Antwort, Klaus!
Ich werde später selbst auch mal probieren, ob die bei mir geht.

l.g
Lee
Do the best job, leave the rest in the hands of God!
  Mit Zitat antworten Zitat
Benutzerbild von Boyington
Boyington

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

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 23. Mai 2012, 23:27
Versuch es mal hiermit.
Ich habe die von dir gezeigten daten ins Clipboard kopiert
und von dort in die StringList geschrieben.
Alle Daten wurden korrekt gelesen.
Du solltest das mit list.LoadFromFile machen.
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;
   Dreiecke:Array of TDreieck;

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);
   for i:=1 to 3 do begin
      FindLine(recline,true);
      ReadLine(data.p[i]);
   end;
   SetLength(Dreiecke,Length(Dreiecke)+1);
   Dreiecke[High(dreiecke)]:=data;
end;
// var f:TextFile; i,j:integer; // nur zur Kontrolle benutzt
begin
   Dreiecke:=nil;
   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;
         end;
      end;
   finally
      list.free;
   end;
end;
Guten Abend, Leute
Zwei Fragen an dich, Klaus:

1)für SetLength(Dreiecke,Length(Dreiecke)+1), Length(Dreiecke)+1 darf nur zwischen 0...255 sein, oder? Wenn ein 3D-Objekt z.B nur aus weniger als 255 Dreiecken besteht, ist es in Ordnung, aber wenn es aus 10000 Dreiecken besteht, wie mache ich mit dieser Funktion Dreiecke[256], Dreiecke[257]....bis Dreiecke[10000]?

2)wie kann man nach dem Einlesen der *.stl Datei und nach dem Schreiben aller Koordinaten in Variable "Dreiecke"(array of TDreieck) alle dort gespeicherte Koordinaten wieder in Clipboard kopieren? Damit kann ich alle in Variable "Dreiecke" gespeicherten Koordinaten mit den original Koordinaten mal vergleichen und überprüfen, ob es richtig ist.

Danke für die Antwort im Voraus!

l.g
Lee
Do the best job, leave the rest in the hands of God!

Geändert von Boyington (24. Mai 2012 um 07:33 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

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

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 24. Mai 2012, 01:43
Guten Abend, Leute
Zwei Fragen an dich, Klaus:

1)für SetLength(Dreiecke,Length(Dreiecke)+1), Length(Dreiecke)+1 darf nur zwischen 0...255 sein, wenn ein 3D-Objekt nur aus weniger als 255 Dreiecken besteht, ist es in Ordnung, aber wenn das 3D-Objekt aus 10000 Dreiecken besteht, wie mache ich mit dieser Funktion Dreiecke[256], Dreiecke[257]....bis Dreiecke[10000]?

2)wie kann man nach dem Einlesen der *.stl Datei und nach dem Schreiben aller Koordinaten in Variable "Dreiecke"(array of TDreieck) alle dort gespeicherte Koordinaten wieder in Clipboard kopieren? Damit kann ich die original Koordinaten mit allen in Variable "Dreiecke" gespeicherten Koordinaten mal vergleichen und überprüfen, ob es richtig ist.

Danke für die Antwort im Voraus!

l.g
Lee
@Lee:

Zu (1) :
Wie kommst du auf die Beschränkung bei SetLength?
Ein dynamisches Array kannst du High(integer) lang machen.
Somit dürfte die einzige Beschränkung der verfügbare Speicherplatz sein.

Zu (2) :
So :
Delphi-Quellcode:
PROCEDURE CopyDreiecke(tofile:boolean);
var list:TStrings;
FUNCTION ToStr(v:real):String;
begin
   result:=FloatToStrF(v,ffExponent,7,3)+' ';
   if result[1]<>'-then result:=' '+result;
end;
PROCEDURE AddVector(const v:TVektor);
type TxVector=Array[0..2] of real;
var s,s1: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
            raise Exception.Create('Dreiecke ist leer.');
         for i:=0 to High(Dreiecke) do
            with Dreiecke[i] do begin
               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;
Mit CopyDreiecke(false) stellst du die Daten ins Clipboard, mit CopyDreiecke(true) in die Datei "Log.txt" im Programmverzeichnis.
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
 
#6

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 24. Mai 2012, 07:31
Guten Abend, Leute
Zwei Fragen an dich, Klaus:

1)für SetLength(Dreiecke,Length(Dreiecke)+1), Length(Dreiecke)+1 darf nur zwischen 0...255 sein, wenn ein 3D-Objekt nur aus weniger als 255 Dreiecken besteht, ist es in Ordnung, aber wenn das 3D-Objekt aus 10000 Dreiecken besteht, wie mache ich mit dieser Funktion Dreiecke[256], Dreiecke[257]....bis Dreiecke[10000]?

2)wie kann man nach dem Einlesen der *.stl Datei und nach dem Schreiben aller Koordinaten in Variable "Dreiecke"(array of TDreieck) alle dort gespeicherte Koordinaten wieder in Clipboard kopieren? Damit kann ich die original Koordinaten mit allen in Variable "Dreiecke" gespeicherten Koordinaten mal vergleichen und überprüfen, ob es richtig ist.

Danke für die Antwort im Voraus!

l.g
Lee
@Lee:

Zu (1) :
Wie kommst du auf die Beschränkung bei SetLength?
Ein dynamisches Array kannst du High(integer) lang machen.
Somit dürfte die einzige Beschränkung der verfügbare Speicherplatz sein.

Zu (2) :
So :
Delphi-Quellcode:
PROCEDURE CopyDreiecke(tofile:boolean);
var list:TStrings;
FUNCTION ToStr(v:real):String;
begin
   result:=FloatToStrF(v,ffExponent,7,3)+' ';
   if result[1]<>'-then result:=' '+result;
end;
PROCEDURE AddVector(const v:TVektor);
type TxVector=Array[0..2] of real;
var s,s1: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
            raise Exception.Create('Dreiecke ist leer.');
         for i:=0 to High(Dreiecke) do
            with Dreiecke[i] do begin
               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;
Mit CopyDreiecke(false) stellst du die Daten ins Clipboard, mit CopyDreiecke(true) in die Datei "Log.txt" im Programmverzeichnis.

Morgen Alle,
alles klar, danke für die hilfreiche Antwort

l.g
Lee
Do the best job, leave the rest in the hands of God!
  Mit Zitat antworten Zitat
Benutzerbild von Boyington
Boyington

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

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 28. Mai 2012, 14:08
Hallo Klaus,
ich hab dein Programm vereinfacht, aber es funktioniert einfach nicht (die *.exe Datei kann nicht mehr geschlossen werden nach der Durchführung), es scheint, dass Fehler irgendwo aufgetreten sind (wegen unendlicher Schleife???).

Code:
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
   Dreiecke:Array of TDreieck;


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 TForm1.Button2Click(Sender: TObject);
const
  s1='facet normal';
  s2='vertex';
  s3='endsolid';

var
  s:string;
  //i:integer;
  j:integer;
  L:integer;
  List:TStrings;
  Line:integer;
  data:TDreieck;

begin
   Dreiecke:=nil;
   List:=TStringList.Create;
   List.LoadFromFile(OpenDialog1.FileName);
   Line:=1;

   while (Copy(Trim(List[Line]),1,Length(s3))<>s3) do
   begin
    s:=Trim(List[Line]);
    L:=Length(s);

    if (Copy(s,1,Length(s1))=s1) then
      begin
       data.n.z:=ReadNumber(s,L);
       data.n.y:=ReadNumber(s,L);
       data.n.x:=ReadNumber(s,L);
       inc(Line);

       while (Copy(s,1,Length(s2))<>s2) do inc(Line);
         for j:=1 to 3 do begin
          data.p[j].z:=ReadNumber(s,L);
          data.p[j].y:=ReadNumber(s,L);
          data.p[j].x:=ReadNumber(s,L);
          inc(line);
         end;

       SetLength(Dreiecke,Length(Dreiecke)+1);
       Dreiecke[High(dreiecke)]:=data;
      end

       else inc(Line);
    end;
end;
könntest du vielleicht für mich die Fehler mal suchen und dann korrigieren?
Vielen Dank!

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

Geändert von Boyington (28. Mai 2012 um 14:14 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

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

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 28. Mai 2012, 22:51
Hallo Klaus,
ich hab dein Programm vereinfacht, aber es funktioniert einfach nicht (die *.exe Datei kann nicht mehr geschlossen werden nach der Durchführung), es scheint, dass Fehler irgendwo aufgetreten sind (wegen unendlicher Schleife???).

Code:
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
   Dreiecke:Array of TDreieck;


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 TForm1.Button2Click(Sender: TObject);
const
  s1='facet normal';
  s2='vertex';
  s3='endsolid';

var
  s:string;
  //i:integer;
  j:integer;
  L:integer;
  List:TStrings;
  Line:integer;
  data:TDreieck;

begin
   Dreiecke:=nil;
   List:=TStringList.Create;
   List.LoadFromFile(OpenDialog1.FileName);
   Line:=1;

   while (Copy(Trim(List[Line]),1,Length(s3))<>s3) do
   begin
    s:=Trim(List[Line]);
    L:=Length(s);

    if (Copy(s,1,Length(s1))=s1) then
      begin
       data.n.z:=ReadNumber(s,L);
       data.n.y:=ReadNumber(s,L);
       data.n.x:=ReadNumber(s,L);
       inc(Line);

       while (Copy(s,1,Length(s2))<>s2) do inc(Line);
         for j:=1 to 3 do begin
          data.p[j].z:=ReadNumber(s,L);
          data.p[j].y:=ReadNumber(s,L);
          data.p[j].x:=ReadNumber(s,L);
          inc(line);
         end;

       SetLength(Dreiecke,Length(Dreiecke)+1);
       Dreiecke[High(dreiecke)]:=data;
      end

       else inc(Line);
    end;
end;
könntest du vielleicht für mich die Fehler mal suchen und dann korrigieren?
Vielen Dank!

lg
Lee
Hallo Lee,
eigentlich verspüre ich keine große Lust den Korrektor zu spielen, wenn jemand, dem ich einen perfekt funktionierenden
Code lieferte, diesen vermeintlich "vereinfacht" und in nicht funktionierenden Code umwandelt.
Hab's mir trotzdem mal angeschaut, und ohne viel zu suchen tippe ich darauf dass das Programm in der Zeile while (Copy(s,1,Length(s2))<>s2) do inc(Line); festhängt.
Warum ?!
Weil du zwar korrekt den Zeilenzähler erhöhst, aber die neue Zeile nicht in s stellst.
In der Zeile while (Copy(s,1,Length(s2))<>s2) do inc(Line); prüfst du gegen s und das enthält "facet normal ...."
Also wird "vertex" nicht gefunden, und wenn du dann noch die Überlaufprüfung abgeschaltet hast ....

Was mir noch auffiel:
Du gibst List nicht frei.
Du sprachst in einem der Beiträge von 10000 Dreiecken.
Für 1 Dreieck werden ca. 270 Chars gebraucht für 10000 Dreiecke also 2.7 MB (oder 5.4 MB bei WideChars).
Irgendwann kriegst du dann eine Out of Memory Exception.

Das von mir gewählte Konstrukt sorgt dafür, dass
1) list immer freigegeben wird
2) Dreiecke auf nil gesetzt wird, wenn ein Fehler auftritt.
Deine "Vereinfachung" sorgt für
1) unsicheren Code
2) Memory Leaks

Denk mal darüber nach, ob solch eine Vereinfachung wirklich sinnvoll ist.
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
 
#9

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 29. Mai 2012, 01:11
[QUOTE=Amateurprofi;1168431]
Hallo Lee,
eigentlich verspüre ich keine große Lust den Korrektor zu spielen, wenn jemand, dem ich einen perfekt funktionierenden
Code lieferte, diesen vermeintlich "vereinfacht" und in nicht funktionierenden Code umwandelt.
Hab's mir trotzdem mal angeschaut, und ohne viel zu suchen tippe ich darauf dass das Programm in der Zeile while (Copy(s,1,Length(s2))<>s2) do inc(Line); festhängt.
Warum ?!
Weil du zwar korrekt den Zeilenzähler erhöhst, aber die neue Zeile nicht in s stellst.
In der Zeile while (Copy(s,1,Length(s2))<>s2) do inc(Line); prüfst du gegen s und das enthält "facet normal ...."
Also wird "vertex" nicht gefunden, und wenn du dann noch die Überlaufprüfung abgeschaltet hast ....

Was mir noch auffiel:
Du gibst List nicht frei.
Du sprachst in einem der Beiträge von 10000 Dreiecken.
Für 1 Dreieck werden ca. 270 Chars gebraucht für 10000 Dreiecke also 2.7 MB (oder 5.4 MB bei WideChars).
Irgendwann kriegst du dann eine Out of Memory Exception.

Das von mir gewählte Konstrukt sorgt dafür, dass
1) list immer freigegeben wird
2) Dreiecke auf nil gesetzt wird, wenn ein Fehler auftritt.
Deine "Vereinfachung" sorgt für
1) unsicheren Code
2) Memory Leaks

Denk mal darüber nach, ob solch eine Vereinfachung wirklich sinnvoll ist.
vielen Dank für die sehr ausführlichen Antwort und Hinweise, Klaus.
Ich hab dein erstes Programm (stl-Datei einlesen) gerade probiert, aber leider hab ich folgende Fehlermeldungen bekommen.


http://www.delphipraxis.net/attachme...1&d=1338246528

http://www.delphipraxis.net/attachme...1&d=1338246528

Wegen Fehlermeldung von "PROCEDURE TMain.Test;" (in erstem Bild) hab ich folgende code, die eigentlich zu Procedure TMain.Test gehört, in "procedure TForm1.Button2Click(Sender: TObject);" geschrieben.

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

Dann hab ich das Programm wieder durchgeführt durch Drücken von Button2 "Koordinaten der STL einlesen", bekomme ich zweite Fehlermeldung (in 2. Bild)
Miniaturansicht angehängter Grafiken
001.jpg   002.jpg  
Do the best job, leave the rest in the hands of God!

Geändert von Boyington (29. Mai 2012 um 01:21 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Boyington
Boyington

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

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 29. Mai 2012, 01:28
Folgende ist mein Programm (code von dir gemacht), durch Drücken von Button2 werden STL-Datei eingelesen, und durch Drücken von Button3 wird die Liste in Log.txt gespeichert.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, GLScene, GLMisc, GLVectorFileObjects, GLWin32Viewer, GLFileSTL,
  Menus, ComCtrls, StdCtrls, ExtCtrls, GLTexture, GLObjects, GLHUDObjects;

type
    TVektor = record
    x, y, z: real;
    end;

    TDreieck = record
    n: TVektor;
    p: array[1..3] of TVektor;
    end;
.
.
.
Var
  Form1: TForm1;
  Dreiecke:array of TDreieck;
.
.
.
//PROCEDURE TMain.Test; <--bekomme ich Fehlermeldun

FUNCTION FindLine(const s:string; raiseerr:boolean):boolean;
var
  line:integer;
  list:TStrings;
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; list:TStrings; line: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;
const recline='vertex';
var i:integer; data:TDreieck;
begin
   ReadLine(data.n);
   for i:=1 to 3 do begin
      FindLine(recline,true);
      ReadLine(data.p[i]);
   end;
   SetLength(Dreiecke,Length(Dreiecke)+1);
   Dreiecke[High(dreiecke)]:=data;
end;


// var f:TextFile; i,j:integer; // nur zur Kontrolle benutzt

PROCEDURE CopyDreiecke(tofile:boolean);
var list:TStrings;

FUNCTION ToStr(v:real):String;
begin
   result:=FloatToStrF(v,ffExponent,7,3)+' ';
   if result[1]<>'-then result:=' '+result;
end;

PROCEDURE AddVector(const v:TVektor);
type TxVector=Array[0..2] of real;

var s:string; i:integer; list:TStrings;
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
            raise Exception.Create('Dreiecke ist leer.');
         for i:=0 to High(Dreiecke) do
            with Dreiecke[i] do begin
               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;



procedure TForm1.Button3Click(Sender: TObject);
begin
CopyDreiecke(true);
end;

procedure TForm1.Button2Click(Sender: TObject);
const
   recstart='facet normal';
   recline='vertex';
var list:TStrings; line:integer; data:TDreieck;
begin
   Dreiecke:=nil;
   list:=TStringList.Create;
   try
      try
         //list.text:=Clipboard.AsText;
         List.LoadFromFile(OpenDialog1.FileName);
         line:=0;
         while FindLine(recstart,false) do ReadRecord;
      except
         On E:Exception do begin
            ShowMessage(E.Message);
            Dreiecke:=nil;
         end;
      end;
   finally
      list.free;
   end;
end;

end.
Do the best job, leave the rest in the hands of God!

Geändert von Boyington (29. Mai 2012 um 01:33 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


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 04:58 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz