Autor Beitrag
Physikerpepe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: So 08.08.04 15:05 
Hallo! Ich bin neu hier und wenn ihr folgenden Quelltext lesen werdet, schmunzelt ihr sicher! Aber ich bin Physiker und kein Programierer :D Ich habe flogendes Problem:

Ich möchte gern die Messdaten eines Experimentes auswerten. Diese Daten bekomme ich in Form einer Textdatei die folgendermaßen aussieht:



# Frame #1
0.000 375.853 5673 5
2.548 365.108 15565 19
6.711 349.268 24484 21
8.279 206.230 6018 9
9.341 338.388 9925 9
11.000 331.470 7083 4
# Frame #2
0.000 375.853 5673 5
2.548 365.108 15565 19
6.711 349.268 24484 21
8.279 206.230 6018 9
9.341 338.388 9925 9
11.000 331.470 7083 4
# Frame #3
0.000 375.853 5673 5
2.548 365.108 15565 19
6.711 349.268 24484 21
8.279 206.230 6018 9
9.341 338.388 9925 9
11.000 331.470 7083 4

usw.
In der Originaldatei stehen natürlich zwischen zwei "frames" weitaus mehr Zeilen :D und es gibt auch mehr als nur 3 Frames :) !!!
Nun möchte ich diese Datei so auslesen, das alle Zeilen die Frame enthalten ignoriert werden und dann soll jede der vier Spalten einem Array zugeordnet werden, mit dem ich dann meine weiteren Berechnungen durchführen kann.
Ich hab ein solchen Programm bereits geschrieben, nur denke ich, das es da sicher eine elegantere Metode geben muss! Schaut´s euch bitte an und urteilt selbst! (meine Variante dauert bei hinreicht größen Dateien zuweilen auch sehr lange :( )

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
//------Datei öffnen und Anzahl der Zeilen bestimmen-----------------\\

  AssignFile(Quelldatei, ed_Quelldatei.Text);
  reset(Quelldatei);
  d:=0;

  while not eof(QuellDatei) do
  begin
  readln(Quelldatei, Zeile);
  if Zeile[1] <> '#' then
  d:=d+1;
  end;
  bar.Position := 10;

  setlength(ErsteSpalte, d);
  setlength(ZweiteSpalte, d);
  setlength(DritteSpalte, d);
  setlength(VierteSpalte, d);
  CloseFile(Quelldatei);

  ed_vorher.Text:=floattostr(d);
  bar.Position := 15;
  y:=d-1;
 
//------------Datei nochmal öffnen und Werte auslesen------------------------\\

  j:=0;
  AssignFile(Quelldatei, ed_Quelldatei.Text);
  reset(Quelldatei);
  while not eof(QuellDatei) do
  begin
    readln(QuellDatei, Zeile);
    if Zeile[1] <> '#' then begin
      temp:='';
      for i:=3 to 12 do {Zahl in der ersten Spalte}
      begin
        if Zeile[i] <> '' then
        begin
          if Zeile[i]='.' then
          begin
            temp:=temp + ',';
          end
          else
          begin
           temp:=temp + Zeile[i];
          end;
        end;
      end;
      ErsteSpalte[j]:=strtofloat(temp);
      temp:='';
      for i:=12 to 21 do {Zahl in der zweiten Spalte}
      begin
        if Zeile[i] <> '' then
        begin
          if Zeile[i]='.' then
          begin
            temp:=temp + ',';
          end
          else
          begin
           temp:=temp + Zeile[i];
          end;
        end;
      end;
      ZweiteSpalte[j]:=strtofloat(temp);
      temp:='';
      for i:=22 to 29 do {Zahl in der dritten Spalte}
      begin
        if Zeile[i] <> '' then
        begin
          if Zeile[i]='.' then
          begin
            temp:=temp + ',';
          end
          else
          begin
           temp:=temp + Zeile[i];
          end;
        end;
      end;
      DritteSpalte[j]:=strtofloat(temp);
      temp:='';
      for i:=33 to 37 do {Zahl in der vierten Spalte}
      begin
        if Zeile[i] <> '' then
        begin
          if Zeile[i]='.' then
          begin
            temp:=temp + ',';
          end
          else
          begin
           temp:=temp + Zeile[i];
          end;
        end;
      end;
      VierteSpalte[j]:=strtofloat(temp);
      j:=j+1;
    end;
  end;
  CloseFile(Quelldatei);
  bar.Position := 20;


Ich weiss das sieht nicht schön aus, aber besser kann ich es nicht und ich bin für jeden Verbesserungsvorschlag sehr dankbar!!

mfg
pepe
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: So 08.08.04 15:15 
Hi und :welcome: im Delphi-Forum,
ich glaube dir könnte folgendes helfen:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
var ErsteSpalte,ZweiteSpalte,DritteSpalte,VierteSpalte:array of Extended;
    F:Textfile;
    L:string;
    i:integer;
begin
 AssignFile(Quelldatei, ed_Quelldatei.Text);
 Reset(Quelldatei);

 while not eof(Quelldatei) do
 begin
  ReadLn(F,L);
  Application.ProcessMessages; // langsamer, verhindert das Einfrieren der Anwendung
  if copy(L,1,1)='#' then Continue;
  i:=length(ErsteSpalte); // Neuer Index
  // Alle arrays erweitern
  SetLength(ErsteSpalte,i+1);
  SetLength(ZweiteSpalte,i+1);
  SetLength(DritteSpalte,i+1);
  SetLength(VierteSpalte,i+1);

  // Werte holen
  ErsteSpalte[i]:=StrToFloat(copy(L,1,pos(' ',L)-1));
  Delete(L,1,pos(' ',L));
  ZweiteSpalte[i]:=StrToFloat(copy(L,1,pos(' ',L)-1));
  Delete(L,1,pos(' ',L));
  DritteSpalte[i]:=StrToFloat(copy(L,1,pos(' ',L)-1));
  Delete(L,1,pos(' ',L));
  L:=L+' '; // Evtl. letztes Leerzeichen anhängen (wenn später mehr als 4 Werte)
  VierteSpalte[i]:=StrToFloat(copy(L,1,pos(' ',L)-1));
 end;
 CloseFile(F);
Wenn du die 4 dynamischen Arrays in ein neues Array (Länge=4) einfügst, kannst du noch weiter vereinfachen :wink:

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Physikerpepe Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: So 08.08.04 15:57 
Sensationell, das sieht doch 1000mal vernüftiger aus! Danke für die schnelle und kompetente Antwort!!! :D

Da ich schon mal jem. gefunden habe, der sich mit sowas auskennt, hätte ich noch eine andere Frage:

Das Messgerät, welches mir die Ausgangdatei liefert wird von einem alten DOS-Rechner gesteuert und zwar
über ein Turbo-Pascal-Programm.
Nun hatte ich mir vorgestellt dieses Programm mit Delphi neu zu compileren und in mein (Auswertungs-) Programm
zu integrieren! Natürlich war das eine Wunschvorstellung wie ich feststellen musste, denn Delphi kann mit "crt.tpu"
und "dos.tpu" leider nix anfangen :(
Eine möglichkeit, wäre das TP-Progr. umzuschreiben, aber da werden Befehle verwendet mit denen ich nicht´s anfangen kann!
Könnte ich evt. den TP-Quelltext mal hier rein posten und du schaust ob sich da was machen lässt?

pepe
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: So 08.08.04 16:06 
Hallo, es freut mich, dass mein Code helfen konnte. Mit TPU-Dateien kann Delphi nichts mehr anfangen - das ist richtig. Allerdings finden sich viele Funktionen der Crt.tpu jetzt in SysCtrls wieder. Es wäre schön, wenn du für deine Frage und den damit verbundenen Codepost einen neuen Thread erstellen könntest, damit das Delphi-Forum auch zukünftig so übersichtlich bleibt, wie es jetzt ist. Dann werde ich mich selbstverständlich deiner Frage annehmen :D

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Physikerpepe Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: So 08.08.04 16:31 
Da hast du vollkommen Recht! Übersicht muss sein :D

Habe einen neuen Tread erstellt!

(bitte nicht erschrecken :D )

pepe
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 08.08.04 16:33 
ausblenden Delphi-Quelltext
1:
SetLength(ErsteSpalte,i+1);					

Das dürfte der absolute Speicherkiller werden bei mehreren 1000 Zeilen.
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: So 08.08.04 16:43 
Was schlägst du vor? Die Datei vordem "auslesen" durchzuparsen (so wie im ersten Code) oder auf einen Schlag immer gleich 100 neue Felder zu erstellen, und zum Schluss die unbenötigten zu löschen?

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 08.08.04 16:44 
Zweiterer Vorschlag wäre Sinnvoll.
Physikerpepe Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: So 08.08.04 21:54 
Die Datei hat im Schnitt 6000 bis 50000 Zeilen, je nach Messdauer :D !!

Wenn ich das richtig verstanden habe soll ich statt "i+1", "i+100" schreiben!
dann haben aber meine Arryays nach der prozedur eine Länge von 600000 bis 5000000 !!!???
Nimmt das nicht noch mehr Speicher weg??

Und wie kürze ich dann zum Schluss die Arrays?


pepe
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Mo 09.08.04 12:51 
nein, das funktioniert so einfach nicht. Der Code würde dadurch etwas komplexer. Ich poste nachher noch mal was 8)

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Mo 09.08.04 13:40 
Wichtig: i ist jetzt vom Typ Cardinal - das sollte erstmal für einige Daten reichen :D
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
const MemCount=100; // Hier einstellen, wieviel auf einmal reserviert werden soll.
// Evtl. mal mit 1000 probieren
var ErsteSpalte,ZweiteSpalte,DritteSpalte,VierteSpalte:array of Extended;
    Quelldatei:Textfile;
    L:string;
    i:Cardinal;
begin
 AssignFile(Quelldatei, ed_Quelldatei.Text);
 Reset(Quelldatei);

 i:=0;
 while not eof(Quelldatei) do
 begin
  ReadLn(Quelldatei,L);
  Application.ProcessMessages; // langsamer, verhindert das Einfrieren der Anwendung
  if copy(L,1,1)='#' then Continue;
  if length(ErsteSpalte)<(i+1) then begin
   // Alle arrays erweitern
   SetLength(ErsteSpalte,i+MemCount);
   SetLength(ZweiteSpalte,i+MemCount);
   SetLength(DritteSpalte,i+MemCount);
   SetLength(VierteSpalte,i+MemCount);
  end;
  // Werte holen
  ErsteSpalte[i]:=StrToFloat(copy(L,1,pos(' ',L)-1));
  Delete(L,1,pos(' ',L));
  ZweiteSpalte[i]:=StrToFloat(copy(L,1,pos(' ',L)-1));
  Delete(L,1,pos(' ',L));
  DritteSpalte[i]:=StrToFloat(copy(L,1,pos(' ',L)-1));
  Delete(L,1,pos(' ',L));
  L:=L+' '; // Evtl. letztes Leerzeichen anhängen (wenn später mehr als 4 Werte)
  VierteSpalte[i]:=StrToFloat(copy(L,1,pos(' ',L)-1));


  inc(i); // Neuer Index
 end;
 CloseFile(Quelldatei);

 // Aufräumen
 SetLength(ErsteSpalte,i);
 SetLength(ZweiteSpalte,i);
 SetLength(DritteSpalte,i);
 SetLength(VierteSpalte,i);
end;

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Physikerpepe Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Mo 09.08.04 19:22 
Dankeschön!

pepe