2 Strings vergleichen!



  • while( *x++ == *y++ ) if ( !*x && !*y ) return TRUE;
        return FALSE;
    

    Scheint zu funktionieren ...



  • Belli schrieb:

    Ohne es jetzt zu testen, würde es nicht genügen, ind Swordfishs Version das Inkrement für x zu verlagern:

    while( *x == *y++ ) if ( !*x++ ) return TRUE;
    return FALSE;
    

    So würde es auch funktionieren, mit dem Unterschied zu meiner Version, dass vor dem Verlassen der Funktion mit return TRUE die beiden Pointer noch einmal inkrementiert werden (ist nicht nötig, aber unerheblich).

    Alternativ könnte man eine for-Schleife benutzen:

    for ( ; *x == *y; x++, y++ ) if ( !*x ) return TRUE;
    return FALSE;
    

    Diese erzeugt bei meinem Compiler kürzeren Objectcode, zumindest im Debugmode ohne Optimierung, und nochmal geringfügig kürzer ist bei mir:

    while( *x == *y ) {
           if ( !*x ) return TRUE;
           x++;
           y++;
        }
        return FALSE;
    


  • pyhax schrieb:

    while( *x++ == *y++ ) if ( !*x && !*y ) return TRUE;
        return FALSE;
    

    Scheint zu funktionieren ...

    Nein, das funktioniert nicht und birgt Gefahren für den von mir schon geschilderten Fall von 2 Leerstrings (0 Byte lang), weil hierbei in der if-Abfrage möglicherweise zufällige Zeichen nach den 0-Terminatoren auf 0 getestet werden, da die beiden Pointer schon inkrementiert sind.



  • eq schrieb:

    pyhax schrieb:

    while( *x++ == *y++ ) if ( !*x && !*y ) return TRUE;
        return FALSE;
    

    Scheint zu funktionieren ...

    Nein, das funktioniert nicht und birgt Gefahren für den von mir schon geschilderten Fall von 2 Leerstrings (0 Byte lang), weil hierbei in der if-Abfrage möglicherweise zufällige Zeichen nach den 0-Terminatoren auf 0 getestet werden, da die beiden Pointer schon inkrementiert sind.

    Das stimmt nicht, weil die Schleife dann schon am Anfang bei !*x && !*y abbricht.
    Ich würde sonst Segmentation Fault bekommen. (Im Debugmodus, bekomme ich aber nicht)



  • pyhax schrieb:

    eq schrieb:

    pyhax schrieb:

    while( *x++ == *y++ ) if ( !*x && !*y ) return TRUE;
        return FALSE;
    

    Scheint zu funktionieren ...

    Nein, das funktioniert nicht und birgt Gefahren für den von mir schon geschilderten Fall von 2 Leerstrings (0 Byte lang), weil hierbei in der if-Abfrage möglicherweise zufällige Zeichen nach den 0-Terminatoren auf 0 getestet werden, da die beiden Pointer schon inkrementiert sind.

    Das stimmt nicht, weil die Schleife dann schon am Anfang bei !*x && !*y abbricht.

    Warum sollte sie abbrechen, wenn beide Strings '\0' als erstes Zeichen haben?



  • pyhax schrieb:

    eq schrieb:

    pyhax schrieb:

    while( *x++ == *y++ ) if ( !*x && !*y ) return TRUE;
        return FALSE;
    

    Scheint zu funktionieren ...

    Nein, das funktioniert nicht und birgt Gefahren für den von mir schon geschilderten Fall von 2 Leerstrings (0 Byte lang), weil hierbei in der if-Abfrage möglicherweise zufällige Zeichen nach den 0-Terminatoren auf 0 getestet werden, da die beiden Pointer schon inkrementiert sind.

    Das stimmt nicht, weil die Schleife dann schon am Anfang bei !*x && !*y abbricht.
    Ich würde sonst Segmentation Fault bekommen. (Im Debugmodus, bekomme ich aber nicht)

    Nein, sie bricht bestenfalls zufällig ab, kann dabei aber auch ein falsches Ergebnis liefern oder eben früher oder später Segmentation Fault.
    Ich habe es getestet mit:

    char const* x = "\0" "A";
        char const* y = "\0" "B";
    

    und das Ergebnis ist Ungleichheit.



  • Und für die nächsten 20 Versuche testet es vorher aus und nicht so umständlich wie zuvor:

    #include <assert.h>
    
    enum{FALSE,TRUE};
    
    int equal( char const* x, char const* y ) {
        while( *x == *y ) {
           if ( !*x ) return TRUE;
           x++;
           y++;
        }
        return FALSE;
    }
    
    int main() {
    
      assert(  equal("",  "") );
      assert( !equal("",  "1") );
      assert( !equal("1", "") );
      assert(  equal("1", "1") );
      assert( !equal("1", "11") );
      assert(  equal("ä", "ä") );
      assert( !equal("äÄ","ä") );
    
      return 0;
    }
    

    Speicherzugriffsfehler werden hierbei natürlich auch nicht zuerlässig erkannt, aber immerhin.



  • Belli schrieb:

    Warum sollte sie abbrechen, wenn beide Strings '\0' als erstes Zeichen haben?

    Was ergibt !0?

    Ansonsten im guten alten K&R finden sich folgende Varianten:

    /* strcmp:  return <0 if s<t, 0 if s==t, >0 if s>t */
     int strcmp(char *s, char *t)
       {
           int i;
           for (i = 0; s[i] == t[i]; i++)
               if (s[i] == '\0')
                   return 0;
           return s[i] - t[i];
       }
    

    The pointer version of strcmp:

    /* strcmp:  return <0 if s<t, 0 if s==t, >0 if s>t */
       int strcmp(char *s, char *t)
       {
           for ( ; *s == *t; s++, t++)
               if (*s == '\0')
                   return 0;
           return *s - *t;
       }
    

    Man muss ja nicht alles neu erfinden!



  • God damned! Stimmt. 🤡



  • Shiba schrieb:

    Belli schrieb:

    Warum sollte sie abbrechen, wenn beide Strings '\0' als erstes Zeichen haben?

    Was ergibt !0?

    Es kommt bei dem in Rede stehenden Code aber nicht zu !0, sondern zu !*x, wobei x aber schon über das 0-Byte hinaus inkrementiert wurde.



  • Da hast Du Recht und ich etwas übersehen.



  • Shiba schrieb:

    Ansonsten im guten alten K&R finden sich folgende Varianten:

    Hm.. gab es da noch kein const? oO



  • cooky451 schrieb:

    Shiba schrieb:

    Ansonsten im guten alten K&R finden sich folgende Varianten:

    Hm.. gab es da noch kein const? oO

    Darauf wird es wohl hinauslaufen, ja.



  • K&R hatte noch kein const,void,enum,signed,volatile.


Anmelden zum Antworten