Einzelnen Beitrag anzeigen

Amateurprofi

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

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?

  Alt 28. Mai 2012, 21: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