Entwickler-Ecke

Sonstiges (Delphi) - String auslesen


skaven - Mo 25.10.04 11:19
Titel: String auslesen
Hallo zusammen,

ich würde gernen eine Zeichenkette die so aussieht

'j 1000 4000' pof#*'-->PRD'%&/'45465'##*'-->PRD'hgdas()'45811'#+*'-->' usw.

nach den Zahlen durchsuchen und diese dann ausschneiden und in fortlaufende variablen speichern.

Hab leider keine Idee wie

Ist ja auch Montag.

Hat jemand ne Idee?


jaenicke - Mo 25.10.04 11:24


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var i: Integer;
    s, s2, tmp: String;
begin
    for i:=0 to Length(s) - 1 do
        if s[i] in ['1'..'9','0'then
            s2:=s2+s[i];
    tmp:=s;
    s:='';
    for i:=0 to Length(tmp) - 1 do
        if not (tmp[i] in ['1'..'9','0']) then
            s:=s+tmp[i];


Alle Zahlen in s werden an s2 angehängt. Dann wird s gelöscht und alles außer Zahlen wieder in s getan.


skaven - Mo 25.10.04 11:34
Titel: Noch nicht ganz
Hallo jaenicke,

sieht ganz gut aus, aber ich würde grene zwei einzelen variablen haben, denn ich muß diese am ende vergleichen.

das heißt eine variable wo alle zahlenfolgen die jemals zwischen prd gestanden haben, funktioniert nicht.

Brauche zwie varibale mit je 5 zeichen.

Oder bin ich jetzt total verpeilt und habe dein programm nicht verstanden?

Ja ja, der Montag


skaven - Mo 25.10.04 11:45
Titel: funktioniert nicht
Hi,

würde gerne nur die zahlen zwischen prd und > auslesen. Wie steck ich denn die grenzen das der strig nur zwischen diesen beiden zeichen durchsucht wird?


jasocul - Mo 25.10.04 11:51

Mit der Funktion Pos kannst du die beiden Stellen bestimmen. Dann musst du nur noch die Schleife entsprechend anpassen.


jaenicke - Mo 25.10.04 12:05

@jasocul: Nee, eben nicht, denn dann müsste er für 0 bis 9 je eine Pos-Abfrage machen, denn es ist ja wahrscheinlich nicht bekannt, mit welcher Zahl die Zahlenfolgen anfangen.

Lösung:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var i: Integer;  
    s, s2, s3: String;  
begin  
    i:=0;
    while (i < Length(s)) and not (s[i] in ['1'..'9','0']) do
        Inc(i);
    s2:=Copy(s,i+1,Length(s)-i);
    Inc(i,5);
    while (i < Length(s)) and not (s[i] in ['1'..'9','0']) do
        Inc(i);
    s3:=Copy(s,i+1,Length(s)-i);


s enthält den ursprünglichen String, s2 und s3 die beiden gefundenen 5-ziffrigen Zahlen.


jasocul - Mo 25.10.04 12:10

Stimmt doch. Er hat als Such-Begriff "prd" und ">" vorgegeben.


skaven - Mo 25.10.04 13:04
Titel: ?
Kann mir das jemand mal bitte erklären, verstehe den Code nicht. Wo wird auf PRD hingewiesen?


jasocul - Mo 25.10.04 13:06
Titel: Re: funktioniert nicht
skaven hat folgendes geschrieben:
Hi,

würde gerne nur die zahlen zwischen prd und > auslesen. Wie steck ich denn die grenzen das der strig nur zwischen diesen beiden zeichen durchsucht wird?


Hier?!

und dann:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var i: Integer;    
    s, s2, s3: String;    
begin
    s:=copy(s,pos('PRD',s),pos('>',s)-pos('PRD',s)+1); // ungetestet
    i:=0;  
    while (i < Length(s)) and not (s[i] in ['1'..'9','0']) do  
        Inc(i);  
    s2:=Copy(s,i+1,Length(s)-i);  
    Inc(i,5);  
    while (i < Length(s)) and not (s[i] in ['1'..'9','0']) do  
        Inc(i);  
    s3:=Copy(s,i+1,Length(s)-i);


skaven - Mo 25.10.04 13:47
Titel: eingelesener String
Bei dem letzten Programm ist doch s mein eingelesener string, oder?


jasocul - Mo 25.10.04 13:50

ja.
Wenn du die Kombination PRD > öfter in einem String hast, musst du den String natürlich ein bisschen aufbröseln.


skaven - Mo 25.10.04 14:41
Titel: PRD befehl
Das funktioniert leider nicht, irgendwie wird der PRD Befehl nicht richtig erkannt!


skaven - Mo 25.10.04 14:43

Hier ist mal das komplette Programm, vielleicht fallen den Cracks ein paar Fehler auf. Wäre nett wenn Ihr mal darüber schauen würdet.

Dabke schon mal.


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:
procedure TForm1.DateieinlesenClick(Sender: TObject);
var
   Liste : TStringList;
   i,x, data_length, value_last, value, u : Integer;
   hilftext, data, filename, s, s2, s3 : String;
   prdwerte : array of integer;
   begin
   liste :=tstringlist.create;
  if OpenDialog1.Execute then          { Dialog zum Dateiöffnen anzeigen }
  begin
    filename := OpenDialog1.FileName;
   try
    Liste.LoadFromFile(filename);
    for i := 0 to Liste.Count-1 do
      begin
       apdcomport1.putstring(Liste[i]);     {Übermittelt Daten aus Com1}
       apdcomport1.putstring(#13);
        repeat
         apdcomport1.putstring('prd');
         apdcomport1.putstring(#13);
           while (ApdComPort1.CharReady) do  {ComPort wird komplett ausgelesen}
            begin
             Data := data+ApdComPort1.GetChar;   {ComPort wird ausgelesen}
            end;
       begin
       data:=copy(data,pos('PRD',data),pos('>',data)-pos('PRD',data)+1); {Ermittlung der Zahlenposition}
        u:=0;
        while (u < Length(data)) and not (data[u] in ['1'..'9','0']) do
          Inc(u);
          s2:=Copy(data,u+1,Length(data)-u);
          Inc(u,6);
         while (u < Length(data)) and not (data[u] in ['1'..'9','0']) do
          Inc(u);
          s3:=Copy(data,u+1,Length(data)-u);
       end;
          Setlength(prdwerte,length(prdwerte)+length(data));
          data_length:=length(data);
         for x:=1 to data_length do
          begin
           prdwerte[Length(prdwerte) - Length(Data)] := strtoint(Data[x]);
           delete(data,0,1);
           differenzwert := prdwerte[high(prdwerte)-1]-prdwerte[high(prdwerte)];
           hilftext := inttostr(prdwerte[x]);
           Memo1.text := Memo1.text+hilftext;
          end;
       until data_length<=10;
      end
     finally
    Liste.Free;
   end;
  end;
end;


jasocul - Mo 25.10.04 14:56

Schon mal Schrittweise durch den Source gegangen (Debuggen)?
Lass dir doch mal Anzeigen, was in Data steht.
Was für einen Fehler bekommst du denn, bzw. wie wirkt sich das aus?


skaven - Mo 25.10.04 15:11
Titel: stringzuweisung
Das mit dem Stringauswerten funktioniert nicht richtig.

der erste Teil weird abgeschnitten, aber der rest nicht.


jasocul - Mo 25.10.04 15:18

Der Fehler steckt hier:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
        while (u < Length(data)) and not (data[u] in ['1'..'9','0']) do  
          Inc(u);  
// bis hierhin ok
        s2 := '';
        while (u < Length(data)) and (data[u] in ['1'..'9','0']) do  
        begin
          s2:=s2+Data[u];  
          Inc(u);  
        end;


skaven - Mo 25.10.04 15:30
Titel: Supi
Das hat ja supi geklappt, aber wie mache ich das wenn ich in der zeichenkette mehrere prd´s habe udn alle nacheinander abfragen will und die letzten zwei ermittelten zahlenwerte miteinander vergleichen möchte?

Soviele Fragen, sorry


jojo-sp - Mo 25.10.04 15:35

Ich weis jetzt nicht, in wie weit das schon bedacht wurde, aber wenn die Datenmenge einen bestimmten Wert erreicht hat, wird das ganze nach und nach über Com gesendet.
Hatte nämlich mal das Prob, das mir Daten fehlten.


jasocul - Mo 25.10.04 15:36

Das mit den vielen Frage ist schon ok.
Zum Problem:
Das meinte ich weiter oben mit: "aufbröseln".
Du musst dir immer "Zwischenstrings" basteln.
Also eine weitere Variable, die den Wert bis zum ersten ">" speichert. Aus der anderen Variablen musst du dann den Bereich bis dahin löschen.
Deine Strings sehen dann etwa so aus:
Anfang:
j 1000 4000' pof#*'-->PRD'%&/'45465'##*'-->PRD'hgdas()'45811'#+*'-->'
Erster Schritt:
j 1000 4000' pof#*'-->
PRD'%&/'45465'##*'-->PRD'hgdas()'45811'#+*'-->'
Zweiter Schritt:
PRD'%&/'45465'##*'-->
PRD'hgdas()'45811'#+*'-->'
Fertig.
Du benötigst dafür die String-Funktionen Copy und Delete.
Und eine Schleife, die den ganzen String durchläuft bis kein ">" mehr drin ist.


skaven - Mo 25.10.04 15:46
Titel: Überspringen
Das Problem den ersten String zu überspringen, also "J 1000 ... ", habe ich gelöst.

Mir wird jetzt eine korrekte Zahl ausgegeben. Würde diesen durchlauf gerne so oft wiederholen, wie mir prd werte angeboten werden, max. 20 stück die letzten zwei würde ich gerne in variablen speichern, z.b. last value und value und diese auf >=10 überprüfen.

Hänge Euch nochmal meinen aktuellen Code an.

Riesen DANK jasocul.


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:
procedure TForm1.DateieinlesenClick(Sender: TObject);
var
   Liste : TStringList;
   i,x, data_length, value_last, u : Integer;
   hilftext, data, filename,value : String;
   prdwerte : array of integer;
   begin
   liste :=tstringlist.create;
  if OpenDialog1.Execute then          { Dialog zum Dateiöffnen anzeigen }
  begin
    filename := OpenDialog1.FileName;
   try
    Liste.LoadFromFile(filename);
    for i := 0 to Liste.Count-1 do
      begin
       apdcomport1.putstring(Liste[i]);     {Übermittelt Daten aus Com1}
       apdcomport1.putstring(#13);

       { Bestätigung des ersten Befehles loeschen }
       while (pos('>',data) = 0do
          while (ApdComPort1.CharReady) do  {ComPort wird komplett ausgelesen}
            begin
             Data := data+ApdComPort1.GetChar;   {ComPort wird ausgelesen}
            end;
       data := '';


        repeat
         apdcomport1.putstring('prd');
         apdcomport1.putstring(#13);

       { Zeichen einlesen bis Endzeichen ">" }
         while (pos('>',data) = 0do
          while (ApdComPort1.CharReady) do  {ComPort wird komplett ausgelesen}
            begin
             Data := data+ApdComPort1.GetChar;   {ComPort wird ausgelesen}
            end;
       begin
        // data:=copy(data,pos('PRD',data),pos('>',data)-pos('PRD',data)+1); {Ermittlung der Zahlenposition}
        u:=0;
         {Ermittlung der Zahlenposition}
        while (u < Length(data)) and not (data[u] in ['1'..'9','0']) do
          Inc(u);
          {auslesen und speichern der Zahlen}
         while (u < Length(data)) and (data[u] in ['1'..'9','0']) do
        begin
          value:=value+Data[u];
          Inc(u);
         end;

         {speichern der Zahlenwerte in einem Array}
          Setlength(prdwerte,length(prdwerte)+length(data));
          data_length:=length(data);
         for x:=1 to data_length do
          begin
           prdwerte[Length(prdwerte) - Length(Data)] := strtoint(Data[x]);
           delete(data,0,1);
           // differenzwert := prdwerte[high(prdwerte)-1]-prdwerte[high(prdwerte)];
          // hilftext := inttostr(prdwerte[x]);
           Memo1.text := value;
          end;
         end;
       until data_length<=10;
      end
     finally
    Liste.Free;
   end;
  end;
end;


jasocul - Mo 25.10.04 16:15

Habs mir jetzt nicht im Detail angesehen. Aber du speicherst doch alle ermittelten Werte in einem dynamischen Array. Dann brauchst du doch nur auf die letzten Einträge zu greifen.
Oder habe ich irgendwas übersehen?


skaven - Mo 25.10.04 16:24
Titel: array
Stimmt, das ist die Denkweise, aber leider funktioniert das so nicht wie ich das wollte, irgendwo habe ich mal wieder einen "schönheitsfehler" eingebaut. Hilfe!!!


jasocul - Mo 25.10.04 16:31

Und wieder die Frage:
Was passiert beim Debuggen, bzw was passiert nicht?
Wo läufts falsch?
Welche Auswirkungen?


skaven - Di 26.10.04 09:56
Titel: Falsche Werte
Guten Morgen erst mal zusammen.

Da waren sie wieder meine drei Probleme :D

Und zwar speicher ich die ermittelte Zahl in der Variablen value ab, wenn ich das Programm schrittweise durcharbeite funktioniert das auch super, aber wenn ich es in einem Zug durcharbeiten lasse, und mir am ende die variable in einem memo anzeigen lasse, dann erhalte ich nicht die 6 stellige zahl, sondern eine ca 15 stellige.

Wie kann das denn, muß ich da irgndwo noch eine Zeitverzögerung einbauen?