2 Strings vergleichen!
-
strcmp = soll ich ja gerade nicht benutzen
sonst wär es ja wirklich einfach!
-
Okay, nicht überlegt:
if(!equal(x,y) // Strings sind gleich!
-
Du kannst aber die Funktionalität von strcmp nachprogrammieren.
Und equal würde ich wörtlich nehmen und bei Ungleichheit 0 zurückgeben.
Dann geht sowas:if(equal("Hallo", "Hallo")) puts("Gleich");
-
int equal(char x[], char y[]){ int i = 0; while(x[i] != '\0' && y[i] != '\0') { if(x[i] != y[i]) return 0; /*Keine Gleichheit darum Rückgabewert 0 */ i++; } if(x[i] != y[i]) return 0; /* das hier hat noch gefehlt, falls x und y ungleich lang sind */ return 1; /*Gleichheit darum Rückgabewert 1*/ }
-
DirkB schrieb:
Dann ist
*x++ == *y++
falseNein, nicht wenn bis zur terminierenden 0 bei beim ersten String nur gleiche Zeichen gefunden wurden. Dann ist das Resultat falsch, wenn der 2. String länger als der erste ist. Richtig wird es, wenn der entsprechende Pointer (oder beide) erst nach dem Vergleich auf die 0 erhöht wird.
-
eq schrieb:
DirkB schrieb:
Dann ist
*x++ == *y++
falseNein, nicht wenn bis zur terminierenden 0 bei beim ersten String nur gleiche Zeichen gefunden wurden. Dann ist das Resultat falsch, wenn der 2. String länger als der erste ist. Richtig wird es, wenn der entsprechende Pointer (oder beide) erst nach dem Vergleich auf die 0 erhöht wird.
Kritisch beim zu frühen Inkrementieren des Pointers ist ausserdem der Vergleich von zwei Strings der Länge 0, da hierbei die terminierende 0 übergangen wird.
-
@eq:
Hallo erstmal!
Ich weiß garnicht ob du's wusstest,
aber du redest schwachfug.
-
Swordfish schrieb:
@eq:
Hallo erstmal!
Ich weiß garnicht ob du's wusstest,
aber du redest schwachfug.Ich weiss zumindest, dass genau die von dir hier gepostete Funktion
int equal( char const* x, char const* y ) { while( *x++ == *y++ ) if ( !*x ) return TRUE; return FALSE; }
völlig verbuggt ist, was ich, vermutlich im Gegensatz zu dir, durch Testen auch leicht verifizieren konnte.
-
nich streiten, jetz haben wir die frage doch gelöst
-
HobbyCoder85 schrieb:
nich streiten, jetz haben wir die frage doch gelöst
Ja, aber die Funktion von Swordfish wäre wegen der Kompaktheit die eleganteste,
wäre da nicht der Bug.@Swordfish
Deshalb nochmal zum Üben:#include <stdio.h> #define FALSE 0 #define TRUE 1 #define SWORDFISH 1 /* 1=verbuggt, 0=O.K. */ int equal( char const* x, char const* y ) { #if SWORDFISH /* verbuggt */ while( *x++ == *y++ ) if ( !*x ) return TRUE; return FALSE; #else /* O.K. */ while( *x == *y ) { if ( !*x ) return TRUE; x++; y++; } return FALSE; #endif } int main() { char const* x = "ABC"; char const* y = "ABCD"; printf( "\nequal( x, y ) mit x=\"%s\" und y=\"%s\" --> ", x, y ); if ( equal( x, y ) ) printf( "GLEICH\n" ); else printf( "VERSCHIEDEN\n" ); printf( "\nequal( y, x ) mit y=\"%s\" und x=\"%s\" --> ", y, x ); if ( equal( y, x ) ) printf( "GLEICH\n" ); else printf( "VERSCHIEDEN\n" ); return 0; }
-
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;
-
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.