Dienstag, 11. März 2008

Gleicher als Gleich - Die Tücken des Stringvergleichs / More same as same - the pitfalls of the string comparison

Angenommen, wir haben den folgenden Code in einer Prozedur/Funktion/Methode hinterlegt um den aktuellen Wert einer Listbox in Erfahrung zu bringen:

DO CASE
CASE "LKW" = listbox.value
    ....
CASE "Hänger" = listbox.value
    ...
CASE "LKW+Hänger" = listbox.value
    ...
ENDCASE

Wir werden u.U. nie in den dritten Zweig fallen. Ursache ist die Art und Weise, mit der VFP Strings miteinander vergleicht.

Wenn "LKW+Hänger" ausgewählt wird, dann erfolgt die Abarbeitung des ersten CASE Zweigs, denn nach VFP Logik ist "LKW" = "LKW+Hänger" wahr. Der Ausdruck links vom "=" wird nur mit seiner effektiven Länge von 3 Zeichen mit dem Ausdruck rechts vom "=" verglichen. Und das ist in diesem Fall immer "LKW" und somit für VFP gleich.

Um dieses Verhalten zu beeinflussen besitzt Visual Foxpro zwei relationale Operatoren, die Zeichenfolgen auf Gleichheit überprüfen.

Der =-Operator führt einen Vergleich zwischen zwei Werten desselben Datentyps durch. Dieser Operator eignet sich zum Vergleichen von Daten des Typs Zeichen, Numerisch, Datum und Logisch. Wenn Zeichenausdrücke mit dem =-Operator verglichen werden, kann es jedoch vorkommen, dass das Ergebnis nicht den Erwartungen entspricht. Zeichenausdrücke werden zeichenweise von links nach rechts verglichen, bis entweder die Ausdrücke nicht mehr übereinstimmen, das Ende des Ausdrucks auf der rechten Seite des =-Operators erreicht ist (SET EXACT OFF) oder das Ende beider Ausdrücke erreicht ist (SET EXACT ON).

Der ==-Operator kann verwendet werden, wenn ein exakter Vergleich der Zeichenausdrücke erfolgen soll. Wenn zwei Zeichenausdrücke mit dem ==-Operator verglichen werden, müssen beide Ausdrücke (unabhängig davon, auf welcher Seite des Operators sie sich befinden) genau dieselben Zeichen, einschließlich Leerzeichen, enthalten, um als gleichbedeutend zu gelten.

Die mit SET EXACT festgelegte Einstellung wird ignoriert, wenn Zeichenfolgen mit dem ==-Operator verglichen werden.

Die folgende Tabelle zeigt, wie die Wahl des Operators und die mit SET EXACT festgelegte Einstellung die Vergleichsergebnisse beeinflussen. (Ein Unterstrich steht hier für ein Leerzeichen.)

Vergleich .......... [= + EXACT OFF] . [= + EXACT ON] . [==]
"abc" = "abc" ...... TRUE ............ TRUE ........... TRUE
"ab"  = "abc" ...... FALSE ........... FALSE .......... FALSE
"abc" = "ab" ....... TRUE ............ FALSE .......... FALSE
"abc" = "ab_" ...... FALSE ........... FALSE .......... FALSE
"ab"  = "ab_" ...... FALSE ........... TRUE ........... FALSE
"ab_" = "ab" ....... TRUE ............ TRUE ........... FALSE
""    = "ab" ....... FALSE ........... FALSE .......... FALSE
"ab"  = "" ......... TRUE ............ FALSE .......... FALSE
"__"  = "" ......... TRUE ............ TRUE ........... FALSE
""    = "___" ...... FALSE ........... TRUE ........... FALSE
TRIM("__") = "" .... TRUE ............ TRUE ........... TRUE
""    = TRIM("__") . TRUE ............ TRUE ........... TRUE

TRUE = Übereinstimmung, FALSE = Keine Übereinstimmung Die bessere Codevariante ist demnach die Folgende:

DO CASE
CASE "LKW" == listbox.value
    ....
CASE "Hänger" == listbox.value
    ...
CASE "LKW+Hänger" == listbox.value
    ...
ENDCASE

Keine Kommentare:

Kommentar veröffentlichen