B&R Vergleich zweier Strings

Martin2XK

Level-2
Beiträge
85
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich arbeite mit B&R und der Visu VC 4. Über die F1 Hilfe hab ich die Vergleichsoperation strcmp gefunden. Mit Hilfe dieser möchte ich zwei Strings miteinander vergleichen, aber ich bin mir nicht sicher wie ich den Ausdruck genau schreiben muss. Es gibt auf einer Seite in der Visu ein Eingabefeld. Dort kann man entweder Text oder Zahlen eintragen. Beim ersten Hochfahren des Panels nach einer Neuinstallation des Projektes ist dieses Feld leer. Der Datentyp ist String[10]. Nach erfolgter Eingabe wird gefragt ob man speichern möchte, drückt man auf ja dann wird diese Information auf eine andere Variable kopiert. Falls dieses Feld aber leer sein sollte, dann möchte ich eine Art Default Text schreiben. Das ganze sieht bei mir so aus:

If (strcmp(ADR(Eingabefeld), ADR("")) = 0 Then
strcpy(ADR(Feld2), ADR("Example"))
ENDIF

Sprache ist AB

Ich bin mir nicht sicher ob das so richtig ist. Was genau bedeutet ADR oder ... warum muss ADR im Befehl mit dabei stehen? Sind die "" ausreichend oder muss ein Leerzeichen dazwischen?

Was ist, programmtechnisch gesehen, der Unterschied zwischen strmp(ADR(Variable1), ADR(Variable2)) und dem Befehl Variable1 = Variable2 ? Es sind Strings

Ich würde mich über Antworten sehr freuen.

Gruß
 
Kenne mich bei B&R nicht aus, aber bei Codesys ist ADR der Adressoperator, er ermittelt also die Speicheradresse der jeweiligen Variable. Ein ADR("") wird nicht funktionieren, weil eine Konstante (das "") keine Adresse hat.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Doch, ADR ('BlaBla') funktioniert. Auch bei TwinCat, also vermute ich auch in Codesys.

Aber das ist nicht die Antwort auf die Frage. Die Funktion strnlen oder so ähnlich gibt dir die länge des Strings zurück. Damit kannst du abfragen ob in dem String was drinsteht...
 
Nein, wird nicht funktionieren. Wie gesagt, ich würde auf strnlen wechseln und damit die Anzahl der Zeichen ermitteln.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also Doppelte Anführungszeichen werden bei B&R für WSTRING genommen bei einem normalen String nur die Einfachen...
Und deine Abfrage sollte auch so gehen:

IF Eingabefeld = '' THEN
Feld2 := 'Example';
END_IF

Und beachte immer den Unterschied STRING und WSTRING
 
Hier muss man ein wenig auf die verwendete Sprache aufpassen. Automation Basic (AB) verhält sich in vielen Details anders als ST.

Zum Beispiel:
  • In AB steht ein String-Literal in doppelten Anführungszeichen (z.B. "Error"), ein Einzelzeichen in einfachen Anführungszeichen (z.B. 'a'). WSTRING-Literale brauchen hier einen expliziten Cast (z.B. WSTRING("Error") ).
  • String-Literale werden in AB automatisch in die Adresse umgewandelt, daher funktioniert eine einfache Zuweisung wie Feld2 = "Example" nicht. Es muss die strcpy (oder besser brsstrcpy, siehe unten)-Funktion verwendet werden.
  • Es gibt keine Unterscheidung zwischen dem Vergleichs- und Zuweisungs-Operator, beides ist ein '='.
  • Es braucht keinen Zeilenabschluss (';') wie bei ST.
Um Probleme durch mögliche Kollissionen der B&R String-Funktionen mit den nativen C String-Funktionen zu vermeiden, sollten die Funktionen aus der AsBrStr-Library verwendet werden, diese haben das Präfix "brs".

Der angepasste Code aus dem Ausgangspost lautet also:
Code:
    IF (brsstrcmp(ADR(Eingabefeld), "") = 0) THEN
      brsstrcpy(ADR(Feld2), "Example")
    ENDIF

Die Adressoperatoren ADR() braucht man, weil die Funktionen mit den Adressen (Pointern) der Variablen arbeiten. Bei den String-Literalen geschieht die Umwandlung (in AB) automatisch, bei den Variablen muss man es explizit hinschreiben. Es macht aber meines Wissens nach auch nichts, wenn man ihn auch bei String-Literalen trotzdem hinschreibt. Das heißt, funktionieren sollte der ursprüngliche Code trotzdem.

Für deinen Anwendungsfall macht es keinen Unterschied, ob du die Strings direkt (Variable1 = Variable2) oder über einen Funktionsaufruf (brsstrcmp(ADR(Variable1), ADR(Variable2)) = 0) vergleichst. Die Funktion brsstrcmp() vergleicht die Strings halt lexikalisch, das heißt, du erhältst folgendes Ergebnis:
  • 0 die Strings sind gleich
  • >0 das erste ungleiche Zeichen in Variable1 ist größer als in Variable2
  • <0 das erste ungleiche Zeichen in Variable1 ist kleiner als in Variable2
Der Ansatz mit brsstrlen() = 0 funktioniert natürlich genauso.
 
Dass sich die Stringbehandlung in AB und ST unterscheidet wusste ich bisher auch nicht, liegt auch daran dass ich AB nicht oft verwende.

Aber generell sollten bei Stringhandling die entsprechenden Funktionen verwendet werden. Ich hatte da mal ziemliche Scherereien mit einem Handscanner der an den String noch willkürlich Leerzeichen gehangen hat. Da kam es dann hin und wieder beim vergleich mit "=" sogar zu einem PageFault.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dass sich die Stringbehandlung in AB und ST unterscheidet wusste ich bisher auch nicht, liegt auch daran dass ich AB nicht oft verwende.

Aber generell sollten bei Stringhandling die entsprechenden Funktionen verwendet werden. Ich hatte da mal ziemliche Scherereien mit einem Handscanner der an den String noch willkürlich Leerzeichen gehangen hat. Da kam es dann hin und wieder beim vergleich mit "=" sogar zu einem PageFault.
Das hat schlicht damit zu tun, dass es keinen herstellerübergreifenden String-Standard gibt, und auch noch ein Haufen Zeichenkodierungs-Systeme unterwegs sind.

Bei B&R ist das recht banal, da liegen alle Strings Nullterminiert im Speicher, d.h. nach dem letzten Zeichen kommt ein Byte mit dem Inhalt 0 (also Ascii-Wert 0). Dafür gibt es aber keine Längenbegrenzung. Alle Stringfunktionen setzen drauf auf, besitzen aber keine Längenkontrolle. Wendest du eine Stringfunktion auf irgendeinen x-beliebigen Speicher an, sucht der so lange bis eine 0 im Speicher steht - Page Fault ist vorprogrammiert. Die Sicherheitslücke Heartbleed in openSSL hatte eine ähnliche Ursache.
Siemens wiederum verwendet die Geschichte mit den beiden Startbytes (max. Länge / tatsächliche Länge), d.h. dadurch ergeben sich natürliche Längengrenzen. Bei den Profinet I&M-Datensätze 1, 2 und 3 wiederum ist VisibleString üblich, d.h. die Länge ist oftmals fix, die unbenutzten Zeichen werden mit Leerzeichen befüllt.

Kommen dann noch Kodierungen wie UTF8 ins Spiel, wirds richtig lustig.

Generell ist bei B&R zu beachten, dass Strings immer als Zeiger angegeben werden. Unübersichtlich ist, dass die Compiler bei Stringkonstanten die ADR() (oder * bei C) Operatoren implizit einbauen, ohne das man das merkt. Wirklich verstanden hatte ich das erst nach einem Kurs, in dem das C-Pointerhandling detailliert erklärt wurde.
 
Zurück
Oben