Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi wie kann ich bestimmte Infos aus Textdokument einlesen? (https://www.delphipraxis.net/168443-wie-kann-ich-bestimmte-infos-aus-textdokument-einlesen.html)

Boyington 6. Jun 2012 12:25

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Das ist mein Programm mit Code von Klaus

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 = array[1..3] of real;
    TVektor = record
    x, y, z: real;
    end;

    TDreieck = record
    n: TVektor;
    p: array[1..3] of TVektor;
    end;

    hDreieck = ^TDreieck;

    TMatrix_3x3 = array[1..3, 1..3] of real;
    TMatrix_4x4 = array[1..4, 1..4] of real;
.
.
.
Var
  Form1: TForm1;
  Rotationsmatrix: TMatrix_3x3;
  //Dreiecke:array of TDreieck;
  Dreiecke: TList;
.
.
.
procedure TForm1.Button2Click(Sender: TObject);
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; hDreieck:^TDreieck;
begin
   //ReadLine(data.n);
   New(hDreieck) //neu zugefuegt;
   ReadLine(hDreieck^.n); //Fehlermeldung:missing Operator or Semicolon;
   for i:=1 to 3 do begin
      FindLine(recline,true);
      //ReadLine(data.p[i]);
      ReadLine(hDreieck^.p[i]);
   end;
   //SetLength(Dreiecke,Length(Dreiecke)+1);
   //Dreiecke[High(dreiecke)]:=data;
   Dreiecke.Add(hDreieck);
   
end;


// var f:TextFile; i,j:integer; // nur zur Kontrolle benutzt
begin
   Dreiecke:=nil;
   Dreiecke:=TList.Create;
   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;



//die Liste zur Kontrolle als Log.txt speichern;
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;
begin
   for i:=0 to High(TxVector) do s:=s+ToStr(TxVector(v)[i]);
   list.Add(s);
end;

var i,j:integer; //hDreieck:^TDreieck;
begin
   list:=TStringList.Create;
   try
      try
         //if Length(Dreiecke)=0 then
         if Dreiecke.Count=0 then
            raise Exception.Create('Dreiecke ist leer.');
         //for i:=0 to High(Dreiecke) do
           for i:=0 to Dreiecke.Count-1 do
            //with Dreiecke[i] do begin
             with hDreieck(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;
      for i:=0 to Dreiecke.Count-1 do Dispose(Dreiecke[i]); //neu zugefuegt Code;
      Dreiecke.Free; //neu zugefuegt Code;
   end;
end;

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

end.

Amateurprofi 6. Jun 2012 13:41

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Hallo Lee,
ich hab das mal 1:1 kopiert.

Bei mir wurde das nicht kompiliert, weil in der Prozedur ReadRecord hinter
Delphi-Quellcode:
New(hDreieck)
das Semikolon fehlt.

Nach Hinzufügen des Semikolons lief das einwandfrei.

Ich habe die Daten aus #28 ins Clipboard kopiert und in Button2Click in list gestellt.
Nach Ausführen von Button2Click habe ich die Daten mit CopyDreiecke in Log.txt geschrieben.
Ergebnis : Alle Werte sind identisch mit den Originalwerten.

Dann habe ich die Daten aus #28 in eine Datei gestellt und in Button2Click aus dieser Datei in list geladen.
Nach Ausführen von Button2Click habe ich die Daten mit CopyDreiecke in Log.txt geschrieben.
Ergebnis : Alle Werte sind identisch mit den Originalwerten.

Da das, was du gepostet hast, so wie es war (fehlendes Semikolon), nicht kompiliert wurde, kann ich nicht so recht glauben, dass das die Version war, die bei dir fehlerhafte Ergebnisse brachte, denn die hätte ja gar nicht laufen können.
Aber vielleicht hast du ja so einen Zauberkompiler, der fehlende Semikola toleriert – kann ich aber auch nicht glauben.

Was mir noch auffiel:

Erstens:
Oberhalb der Prozeduren deklarierst du einen Typ
Delphi-Quellcode:
hDreieck=^TDreieck
.
In der Prozedur ReadRecord deklarierst du eine Variable
Delphi-Quellcode:
hDreieck=^TDreieck
.
Das ist zwar unkritisch aber unschön.
Sinnvoller wäre, die Variable als z.B.
Delphi-Quellcode:
Dreieck:hDreieck
zu deklarieren.

Zweitens:
Im Except Block in Button2Click schreibst du Dreiecke:=nil;
Wenn es tatsächlich zu einer Exception kommt erzeugst du damit schöne Memory Leaks.
Richtig wäre.
Delphi-Quellcode:
for i:=0 to Dreiecke.Count-1 do Dispose(Dreiecke[i]);
Dreiecke.Free;
Drittens:
Du lädtst eine Datei deren Namen du aus OpenDialog.Filename entnimmst.
Kann es sein, dass da ein anderer Dateiname steht, als du vermutest ?

Boyington 6. Jun 2012 16:07

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Nachdem ich den "schönen kleinen" Semikolon zugefügt habe, funktioniert diesmal die original Code (Eingabe+Ausgabe) von Klaus bei mir ganz gut, und Gott sei dank, mein eigenes Programm (*.STL Datei Einlesen basiert auf Code von Klaus) läuft auch so gut (vorher hab ich New(hDreieck) irgendwo zweimal geschrieben, deshalb falsche Koordinaten bekommen).

Danke für alle Antworten, besonders für Antworten von Klaus und Bummi:-D

wünsche euch einen schönen Tag (vielleicht schönen Abend) noch!

Gruss
lee


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:02 Uhr.
Seite 4 von 4   « Erste     234   

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