# String vergleichen bzw. finden



## bastler (26 Dezember 2014)

Hallo
Ich möchte aus einer String-Variable (Eingangstext) drei Strings suchen lassen. Sind diese vorhanden 
soll ein Ausgang gesetzt werden.
Folgenden Code habe ich geschrieben:


```
Wort1 := FIND('ABC', Eingabetext);
Wort2 := FIND('DEF', Eingabetext);
Wort3 := FIND('GHI', Eingabetext);

IF Wort1 >0 AND Wort2 >0 AND Wort3 >0
    THEN Ausgang:=TRUE;
END_IF
```

Wenn ich online schaue, sehe ich, das die String-Variable "Eingangstext" die drei zu suchenden Strings beinhaltet. Aber die INT-Variablen Wort1, Wort2 und Wort3 bleiben auf 0.
Diese drei Variablen sollten mir doch aber eigentlich die gefundene Position als Integer anzeigen.
Was mach ich denn da noch falsch?

Edit: Wenn ich so vergleiche, "Wort3 := FIND('GHI', 'GHI');" funktioniert es. Irgendwie gibt es Probleme mit der Variable "Eingabetext".

MfG
bastler


----------



## shrimps (26 Dezember 2014)

Hallo Bastler,
ich bin zwar auch Neuling in Sachen Codesys / Twincat aber du hast einfach nur die beiden Operanden vertauscht !
Ich habs gerade nochmal nachgelesen, erst der Textstring, dann der Suchstring.
Deswegen hat auch dein Edit funktioniert.

Gruss
Shrimps

BTW: Habe gerade vergessen, ich habe es ausprobiert !

Und, falls du nur reagieren möchstest ob eines der Drei Suchworte richtig ist, ist Bool ggf. angenehmer !
Mein Code:
    tText1    : STRING := 'Das ist einAbC ohne wenn und aber';
    iPos        : INT;
    bFound : BOOL;

iPos := FIND(tText1, 'AbC');

bFound := FIND(tText1, 'AbC') > 0;
bFound := bFound OR FIND(tText1, 'nein') > 0;
bFound := bFound OR FIND(tText1, 'ein') > 0;

Ipos ist dein Beispiel und bFound die Alternative...


----------



## bastler (26 Dezember 2014)

Hallo Shrimps
genau das war's. Tausend Dank.

MfG
bastler


----------



## bastler (27 Dezember 2014)

Zum Thema String hätte ich noch eine Frage.
Wie kann man herausbekommen, wie oft ein String in einen anderen String vorhanden ist?
Habs mit "FIND" probiert, aber da bekomme ich ja nur die erste gefundene Stelle angezeigt.
Ein Denkanstoß würde mir schon helfen.

MfG
bastler


----------



## shrimps (27 Dezember 2014)

Hallo Bastler,
da gibt es "1000" Lösungen:
Bsp:
Du suchst in einer Schleife mit deinem Find und "löscht" anschl. den gefunden Teil.
Nun bis 0 Found weitersuchen...

Oder mit Substr den String kürzen, ich kannste den delete aus anderen Sprachen nicht.

Oder einen Pointer (Suchergebnis der ersten Suche) mitlaufen lassen und immer in substr() ab Position Pointer+1 suchen

oder...

LG
Shrimps


----------



## bastler (27 Dezember 2014)

Der String darf nicht verändert werden, weder Zeichen löschen noch überschreiben.
Das ist warscheinlich auch das schwierige daran, dass der String nicht verändert werden soll.
Ich hab null Plan wie das gehen soll.


----------



## shrimps (27 Dezember 2014)

Hallo Bastler,
hier n fertiger Code zum Lernen...

LG
Shrimps

```
FUNCTION FindCount : INT
VAR_INPUT
    sText    : STRING;
    sSuche    : STRING;
END_VAR
VAR
    iPos        : INT;
    iLen        : INT;
END_VAR

iLen := LEN(sText);

FindCount := 0;

iPos := FIND(sText, sSuche);
WHILE iPos > 0 DO

    FindCount := FindCount +1;
    iLen := iLen - iPos;
    iPos := iPos + LEN(sSuche);

    iPos := FIND(MID(sText, iLen, iPos), sSuche);

END_WHILE


END_FUNCTION


PROGRAM MAIN
VAR

    sT1            : STRING;
    sSu            : STRING;
    Schritt        : INT;
    nGefunden    : INT;
  
END_VAR

sT1     := 'Dies ist der eingegebene Text zum durchsuchenz';
sSu     := 'e';

CASE schritt OF

0:    nGefunden := FindCount(sT1,sSu);
    Schritt := Schritt +1;

1:    ; (* nada *)

END_CASE


END_PROGRAM
```


----------



## bastler (27 Dezember 2014)

Vielen lieben Dank, werde mich mal dran machen, das zu verstehen.

MfG
bastler


----------



## bastler (1 Januar 2015)

Erst mal allen ein gesundes neues Jahr.
Ich muss zu den og Problem nochmal nachhaken.
Der Code von shrimps funzt bei mir irgendwie nicht.
Ich hab mir jetzt folgendes überlegt:

```
VAR_INPUT
    sText    : STRING(200);
    sSuche    : STRING;
END_VAR
VAR
    found:         INT;
    iPos        : INT;
    iLen        : INT;
END_VAR

slen := Len(sText);
found := Find(sText, sSuche);
pos := Right(sText, slen - found - 2);
```

Ich  ermittle die Länge des Strings. Danach suche ich nach den zu suchenden  Zeichen im String. Die zu suchenden Zeichen ist eine Zeichenkette von 3  Zeichen.
Wenn diese 3 Zeichen gefunden wurden, lasse ich mir den  String (pos) so anzeigen, das nur die Zeichen die rechts von der  Fundstelle minus den 3 gesuchten Zeichen angezeigt werden.
Bis hier funktioniert das alles auch und so wollte ich das auch haben.
Aber:
Wie  muss ich den Code in eine Schleife einbinden, das der String bis zum  Ende durchsucht wird und wie kann ich die Schleifendurchläufe zählen?

MfG
bastler


----------



## shrimps (1 Januar 2015)

Hallo Bastler,
ich habe nochmal nachgetestet.
Wenn ich bei mir als Suchstring 'en' vorgebe, dann findet er ihn auch 2 mal.
Nun ist mir unklar was bei dir nicht geht ?
Alles was du jetzt fragst ist in dieser Funktion untergebracht:
Schleife, Weiterlesen ab gefundener Position etc.


Du brauchst doch nur noch meine Funktion bei dir hinzufügen und irgenwo im Code aufrufen.
Mein main-prg dient ja nur als Hülle zum Testen !

Gerne helfe ich weiter...

Soll ich ggf. mal alles durchkommentieren und nochmals einstellen ?

Eine Function zu testen (debuggen) scheint etwas umständlich zu sein, daher ist es ggf. im Hauptprogramm einfacher...
GGf. kann ich das auch alles in das Main packen ?
Ist dir in meinem Beispiel die Schrittkette im weg ?


Beste Grüße
Shrimps


----------



## Irek (1 Januar 2015)

Hab was:
PROGRAM MAIN
VAR
    Such_String:STRING(255);
    Wort1:STRING;
    Suche_nach:STRING;
    L_Surce:INT;
    L_Search:INT;
    i: INT;
    _Resultat: INT;
END_VAR

Such_String:='Wir suchen nach mindestens drei verschiedenen Eingaben, die eifach gefunden werden sollen, wenn drei zwi mal vorkommt';(*Hier wird gesucht*)
Wort1:='drei';(*danach wird gesucht*)
L_Surce:=LEN(Such_String);(*Stringlaenge Qellstring*)
L_Search:=LEN(Wort1);(*Hier der Suchstring*)
i:=0; (*Soll uch dabei sein*)
WHILE i < (L_Surce-L_Search) DO (*Wir beenden die Suche an der richtigen Stelle*)
    Suche_nach:=MID(STR:=Such_String,LEN:=L_Search,POS:=i);
    IF (Suche_nach=Wort1) THEN _Resultat:=_Resultat+1;END_IF;(*fall mehrmals vorgekommen*)
    i:=i+1;
END_WHILE;


----------



## shrimps (2 Januar 2015)

Hallo zusammen,
damit man das alles mal tracen kann, habe ich es als Schrittkette formuliert.

Beste Grüße Shrimps


```
PROGRAM MAIN
VAR
    zch            : STRING;
    text            : STRING;
    Helfer        : STRING;
    Position        : INT;
    laenge        : INT;
    Anzahl        : INT;
    schritt        : INT;
END_VAR

CASE schritt OF

0:
    text     := 'Dies ist der eingegebenze Text zum durchsuchenz';
    helfer := text;
    zch     := 'enz';
    laenge := LEN(helfer);
    schritt := schritt +1;

1:
    Position := FIND(Helfer,zch);
    IF position > 0 THEN
        Anzahl     := Anzahl +1;
        laenge      := laenge - position - LEN(zch) +1;
        helfer     := MID(helfer,laenge,position + LEN(zch));
    ELSE
        schritt := 99;
    END_IF

99:; (* fertig *)

END_CASE
```


----------



## shrimps (3 Januar 2015)

Hallo Bastler,
nun läufts (zumindest bei mir )

Ich hab mal alles kommentiert

Viel Spaß 
LG
Shrimps


```
FUNCTION Anzahl : INT
VAR_INPUT
    zch        : STRING;    (* Der Suchstring *)
    text        : STRING;    (* Der zu durchsuchende Text *)
END_VAR
VAR
    Position     : INT;        (* Die ggf. gefundene Position *)
    Laenge     : INT;        (* Die aktuelle Laenge des (Restlichen) Textes *)
    Hilfsstring : STRING;    (* Hier drin wird der Teilstring gesichert, ist leichter zu debuggen *)
END_VAR

Hilfsstring     := text;                (* Wir sichern das Original *)
Laenge         := LEN(Hilfsstring);        (* Nun die Startlaenge ermitteln *)
Anzahl := 0;                        (* Wir starten mit 0 gefundenen *)

Position := FIND(Hilfsstring, zch);        (* Eine erste Suche *)

WHILE Position > 0 DO                (* Nun solange zwischen While / end_while laufen bis nichts mehr gefunden wurde *)

    Anzahl         := Anzahl +1;        (* Da wir hier angekommen sind, haben wir einen Treffer *)

    Laenge         := LEN(Hilfsstring) - Position - LEN(zch) +1;        (* Die Restlaenge berechnen, hier hatte ich den Fehler (+1 vergessen) *)
    Hilfsstring     := MID(Hilfsstring,laenge,position + LEN(zch));    (* Den neuen Reststring zusammenbauen *)
    Position         := FIND(Hilfsstring, zch);                    (*  Nun innerhalb der Schleife suchen, dito oben *)

END_WHILE

(* Hier ist das Ende wenn Position = 0 wird *)
(* Der Rücksprung einer Funktion übermittelt automatisch den letzten Wert der Funktion: Anzahl, hier oben als INT definiert *)

PROGRAM MAIN
VAR
    Beispiel        : STRING ;    (* Hier legen wir die Eingabe rein *)
    Suche          : STRING ;    (* Dies simuliert den Suchtext *)
    Cnt1, Cnt2    : INT;        (* Dies ist der Zaehler für das Ergebnis der eigenben Funktion *)
END_VAR

beispiel     := 'Dies ist der eingegebenze Text zum durchsuchenz';    (* Vorbelegn des Beispiels *)
Suche    := 'enz';                                            (* dito Suchtext *)

Cnt1 := Anzahl(suche,beispiel);                                (* Aufruf der eigenen Funktion *)

(* darf man auch so machen: *)

Suche    := 'i';                                                        (* dito Suchtext *)
Cnt2 := Anzahl(zch:= Suche, text:= Beispiel);                                (* Aufruf der eigenen Funktion *)
```


----------



## bastler (3 Januar 2015)

Hallo shrimps
Tausend Dank an shrimps, jetzt läuft alles wie es soll. 
Auch den Code von mir konnte ich erfolgreich einbinden.
Nochmals vielen, vielen Dank für die Arbeit, die du dir gemacht hast.


----------

