Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Bestimmte Daten aus Stringlist auslesen (https://www.delphipraxis.net/147639-bestimmte-daten-aus-stringlist-auslesen.html)

Ducksoul 12. Feb 2010 22:17


Bestimmte Daten aus Stringlist auslesen
 
Guten Abend,

ich habe ein File in eine Stringlist gelesen, welche ich nun Zeile für Zeile durchgehe. Der Aufbau des Files ist eine unbekannte Anzahl von Folgen folgenden Ausdrucks:

Delphi-Quellcode:
Job:               J001
  Comment:           Job 1
  RGB:               55;251;61
  Release:           0
  Due:               0
  Weight:            1
  Oper:              M1;1;A
  Oper:              M2;5;A
  Oper:              M3;3;A
  Oper:              M4;7;A
Auch die Anzahl der "Oper:" ist unbekannt.

Mir stellen sich nun folgendes Problem: Ich weiß nicht wie ich eine Schleife anlegen soll, welche pro Job jede Zeile ausliest. Bis jetzt habe ich eine Whileschleife, welche bis zum Ende der Stringlist läuft. Ist innerhalb dieser [i]pos('Job:', Stringliste) <> 0, so springe ich in eine if-Schleife, in welcher ich nun die Daten pro Job auslesen möchte. Interessieren mich da pro Job eigentlich nur die Zahlen zwischen den Symikoli pro Oper, welche in ein Array geschrieben werden sollen.

Zweites Problem: Kann ich eine Zeile von rechts nach links durchsuchen? Also vom Ende bis zum ersten Leerzeichen?


Ich hoffe ihr könnt mir helfen. in C++ hab ich das Ganze gebacken bekommen. Da wird allerdings alles Wort für Wort durchsucht und nich Zeile für Zeile.



Gruß
Franz

daywalker9 12. Feb 2010 22:23

Re: Bestimmte Daten aus Stringlist auslesen
 
Hallo Franz,


zu deinem zweitem Problem:

Delphi-Quellcode:
procedure Test;
var
 meinString : String;
  i : Integer;
begin
  for i:=high(meinString) downto 1 do
    begin
      if meinString[i] = ' ' then
        begin
          //tu was....
        end;
    end;
end;

Ducksoul 13. Feb 2010 13:01

Re: Bestimmte Daten aus Stringlist auslesen
 
Hallo Daywalker. Danke für deinen Tipp. Die Funktion high() kannte ich noch gar nicht.

Meine erste Frage hat sich auch geklärt. Ich war gestern anscheinend einfach zu müde. Ich hatte bei der Zeile, welche im unten stehenden Code x := i+1 das "+1* vergessen und deswegen wurde natürlich immer gleich im ersten Durchlauf der darunterstehenden Schleife ein "Job:" gefunden...

Delphi-Quellcode:
jobCount := 0; // Jobanzahl zu Beginn = 0
  i := 0;  // Schleifenzähler für while-Schleife
  while i < Bufferlist.Count - 1 do
  begin
    if Pos('Job:', Bufferlist[i]) <> 0 then // wenn in Zeile[i] Job vorhanden...
    begin;
      c := 0;  // Arrayzähler = 0
      SetLength(jobArray, jobCount+1);
      jobArray[jobCount].j_id := jobCount-1;
      x := i+1;
      a := Bufferlist.Count;

      while x < a do // von Zeile i bis zur nächsten Zeile mit Job, oder Dateiende
      begin
        if Pos('Job:', Bufferlist[x]) <> 0 then
          a := x; // Schleifenenabbruch festlegen

        if Pos('Oper:', Bufferlist[x]) <> 0 then // falls Oper in Zeile
        begin
          a := PosEx(';', Bufferlist[x], 1);
          b := PosEx(';', Bufferlist[x], a+1);
          SetLength(jobArray[jobCount].j_proc, c+1);
          jobArray[jobCount].j_proc[c] := StrToInt((Copy(Bufferlist[x], a+1, b-a-1))); // Kopiere Prozesszeit in Array
          Inc(c);  // Arrayzähler um eins erhöhen
        end; // if
        Inc(x);
      end; // while

      Inc(jobCount); // Jobanzahl um eins erhöhen
      SetLength(jobArray, jobCount-1);
    end; // if
    Inc(i);
  end; // while

Für Codeverbesserungen bin ich natürlich immer offen, aber zumindest läuft es so :)


Danke nochmals
Franz

Edit(13.02. 14:42) - Das Einlesen der Prozesszeit ins Array ist noch nicht korrekt. Ich werde die obige Funktion später nochmal editieren.

Ducksoul 13. Feb 2010 18:21

Re: Bestimmte Daten aus Stringlist auslesen
 
Ich habe grade sage und schreibe eine Stunde nach dem Fehler in der Schleife gesucht:

Die Schleife funktioniert so nicht, da die Variable a zweimal benutzt wird. Einmal um die Position des Semikolons im String auszulesen und dann nochmal als Endbedingung für die while-Schleife. Klappt so natürlich nicht...

Und da mir der Fehler erst aufgefallen ist, als ich schon ne andere Schleife geschrieben hatte, kann ich jetz hier noch eine zweite Alternative anbieten:

Delphi-Quellcode:
  while i < Bufferlist.Count - 1 do
  begin
    if Pos('Job:', Bufferlist[i]) <> 0 then // wenn in Zeile[i] Job vorhanden...
    begin;
      //ShowMessage(Bufferlist[i]);
      SetLength(jobArray, jobCount+1);
      SetLength(jobArray[jobCount].j_proc, wcCount-1);

      x := i+1;
      c := 0;

      while (Pos('Job:', Bufferlist[x]) = 0) and (x < Bufferlist.Count - 1) do
      begin
        if Pos('Oper:', Bufferlist[x]) <> 0 then // falls Oper in Zeile
        begin
          a := PosEx(';', Bufferlist[x], 1);
          b := PosEx(';', Bufferlist[x], a+1);
          jobArray[jobCount].j_proc[c] := StrToInt((Copy(Bufferlist[x], a+1, b-a-1))); // Kopiere Prozesszeit in Array
          Inc(c);  // Arrayzähler um eins erhöhen
        end; // if
        Inc(x);
      end; // while

      Inc(jobCount); // Jobanzahl um eins erhöhen
      SetLength(jobArray, jobCount-1);
    end; // if
    Inc(i);
  end; // while
Jetz sag mir bitte noch einer warum ich immer ne Zugriffsverletzung bekomme, wenn ich in einer anderen Methode jobarray[0].j_proc[0] auslese :(

himitsu 13. Feb 2010 18:43

Re: Bestimmte Daten aus Stringlist auslesen
 
Delphi-Quellcode:
for i := 0 to Bufferlist.Count - 1 do
  if Pos('Job:', Bufferlist[i]) <> 0 then
  begin
    jobIdx := Length(jobArray);
    SetLength(jobArray, jobIdx + 1);
    jobArray[jobIdx].j_id := jobIdx;
    for x := i + 1 to Bufferlist.Count - 1 do
    begin
      if Pos('Job:', Bufferlist[x]) <> 0 then
        break;
      if Pos('Oper:', Bufferlist[x]) <> 0 then
      begin
        a := Pos(';', Bufferlist[x]);
        b := PosEx(';', Bufferlist[x], a+1);
        if (a <> 0) and (b <> 0) then
        begin
          //procIdx := Length(jobArray[jobIdx].j_proc);
          //SetLength(jobArray[jobIdx].j_proc, procIdx + 1);
          //jobArray[jobIdx].j_proc[procIdx] := StrToInt(Copy(Bufferlist[x], a+1, b-a-1));
          SetLength(jobArray[jobIdx].j_proc, Length(jobArray[jobIdx].j_proc) + 1);
          jobArray[jobIdx].j_proc[High(jobArray[jobIdx].j_proc)] := StrToInt(Copy(Bufferlist[x], a+1, b-a-1));
        end;
      end;
    end;
  end;
Mit aussagefähigeren Variablen wären die ganzen verwirrenden Kommentare überflüssig und du würdes nicht ausversehn eine Variable doppelt verwenden.
Dank deiner ordentlichen Einrückng brauchst du auch nicht die ganzen END nochmals zu kommentieren.
> gerade hochgegangen sieht man ja wozu sie gehören.

Wenn du die Indize aus ihren zugehörigen Arrays ableitest, dann müßtest du nicht extra mitzählen.

Sicherheitshalber eine Prüfung, ob die Pos/PosEx auch alle nötigen ";" gefunden haben, kann nicht schaden ... eventuell könnte man im Fehlerfall auch noch was machen, bzw. eine Fehlermeldung ausgeben.

PS: Wenn du dort FOR nutzen würdest, wo es paßt, anstatt mit WHILE rumzukämpfen, dann hätte dich sogar der Compiler auf die doppelte Verwendung hingewiesen.

PSS: eine Schleife würde auch ausreichen :zwinker:
Delphi-Quellcode:
for i := 0 to Bufferlist.Count-1 do
  if Pos('Job:', Bufferlist[i]) <> 0 then
  begin
    jobIdx := Length(jobArray);
    SetLength(jobArray, jobIdx+1);
    jobArray[jobIdx].j_id := jobIdx;
  end
  else if Pos('Oper:', Bufferlist[i]) <> 0 then
  begin
    a := Pos(';', Bufferlist[i]);
    b := PosEx(';', Bufferlist[i], a+1);
    jobIdx := High(jobArray);    
    procIdx := Length(jobArray[jobIdx].j_proc);
    if (a > 0) and (b > 0) and (jobIdx >= 0) then
    begin
      SetLength(jobArray[jobIdx].j_proc, procIdx+1);
      jobArray[jobIdx].j_proc[procIdx] := StrToInt(Copy(Bufferlist[i], a+1, b-a-1));
    end;
  end;

Ducksoul 13. Feb 2010 19:06

Re: Bestimmte Daten aus Stringlist auslesen
 
Hachja, ich geb mir schon allergrößte Mühe ordentlichen Code zu schreiben. Aber da gehört wohl noch n bissl Übung dazu.

Dein Code funktioniert jetzt aber wunderbar. :) Ich muss mir morgen dann nochmal angucken, was ich nu bei der Arrayzuweisung falsch gemacht habe.

Danke :thumb:

himitsu 13. Feb 2010 19:14

Re: Bestimmte Daten aus Stringlist auslesen
 
Deine Codeformatierung ist ja schon recht gut, also da kann man nur loben. :thumb:
(sowas ist leider recht selten geworden)

Und das mit den Variablen/Bezeichnungen lernst du auch noch.
(hey, jetzt kennst du immerhin diese "Falle" und entdeckst beim nächsten Problem sowas sofort)

Ducksoul 13. Feb 2010 19:23

Re: Bestimmte Daten aus Stringlist auslesen
 
Ich muss es nochmal sagen:

Deine letzte Schleife gefällt mir äußerst gut. Wenn man sie erstmal vor sich hat ist sie komplett einleuchtend. Da wundert man sich, dass man nicht von allein auf solch simple Lösungen kommt. *g*

himitsu 13. Feb 2010 19:31

Re: Bestimmte Daten aus Stringlist auslesen
 
Man sollte nur den einen Fehler übersehn ... es muß and (jobIdx >= 0) heißen und nicht nur > . :oops:

Ducksoul 14. Feb 2010 09:37

Re: Bestimmte Daten aus Stringlist auslesen
 
Ach so genau hatte ich mir die Schleife noch gar nicht angeschaut. Kleine Fehler können schonmal passieren *g*


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:05 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