PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ Funktion "StrCmp" selbst schreiben


N!mrod
2006-01-19, 15:57:34
Moin!

Ich muss die Funktion "strcmp", welche schon in einer Standard C Bibliothek vorhanden ist, selbst schreiben. Nur leider hab ich keinen Plan wie ich das realisieren soll. Als Anhaltspunkt hab ich nur den Anfang der Funktion..

int mystrcmp(const char *s1, const char *s2);

Ich hoffe jemand versteht mein Problem und kann mir helfen. :)

noid
2006-01-19, 16:06:53
Einfach eine Schleife was den Array abläuft (Länge über Strlen, oder weiterinkrementieren bis "\0") und jeweils die beiden Zeichen Vergleich.

soweit ok?

Coda
2006-01-19, 16:09:32
Das ist eigentlich simpel...

int mystrcmp(const char *s1, const char *s2)
{
for(int i=0;;++i) {
if(s1[i] < s2[i]) return -1;
else if(s1[i] > s2[i]) return 1;
else if(!s1[i]) return 0;
}
}

Imperator Katarn
2006-01-19, 16:16:25
Das ist eigentlich simpel...

int mystrcmp(const char *s1, const char *s2)
{
for(int i=0;;++i) {
if(s1[i] < s2[i]) return -1;
else if(s1[i] > s2[i]) return 1;
if(!s1[i]) return 0;
}
}das würde im Fall
s1 = "abcd";
s2 = "abcde" // strlen(s2) > strlen(s1)0 zurückgeben. 0 sollte aber nur bei Gleichheit beider Strings zurückkommen. Autsch...

Edit: nee gar nicht wahr. Im Beispiel wäre s1[4] = '\0' = 0, und s2[4] = 'e' > 0, was dem Fall s1[4] < s2[4] entspricht. OK :)

Coda
2006-01-19, 16:23:53
Wollt grad was sagen :P

N!mrod
2006-01-19, 16:29:43
Thx! Werd mal schaun ob ichs schaffe das zu implementieren. Bin nich so der C++ Held. ;)

Coda
2006-01-19, 16:46:56
Das ist C++ X-D

Gast
2006-01-19, 19:42:30
int strcmp(const char *str1, const char *str2)
{
while (*str1 == *str2 && *str1 != '\0' )
++str1, ++str2;
return *str1 - *str2;
}

Das _IST_ es! (wie man so schön sagt: possible implementation)

Coda
2006-01-19, 20:46:17
Hm. Das gibt aber auch andere Werte außer -1, 0 und 1 aus, das ist laut Spec anders.

Pinoccio
2006-01-19, 20:47:53
int strcmp(const char *str1, const char *str2)
{
while (*str1 == *str2 && *str1 != '\0' )
++str1, ++str2;
return *str1 - *str2;
}

Das _IST_ es! (wie man so schön sagt: possible implementation)Ohne jegliche Ahnung von C/C++: kommt bei dir unter Umständen nicht auch etwas anderes raus als -1, 0 oder +1?

mfg Sebastian

/edit: och menno, zu langsam. :-(

/edit2: Hm, also wenn die ISO das so erlaubt ... JAVA macht es anders. Hatte ich schon erwähnt, daß ich JAVA mag und C/C++ nicht? ;D

Gast
2006-01-19, 20:59:24
Dann zeigt mir mal wo steht dass es nur -1/0/1 zurück gibt... Leute wenn man keine Ahnung hat...

Ansi/Iso '99 (ISO/IEC 9899:1999):The strcmp function returns an integer greater than, equal to, or less than zero, accordingly as the string pointed to by s1 is greater than, equal to, or less than the string pointed to by s2.

Coda
2006-01-19, 21:03:31
Hm hast recht. Trotzdem machen das alle Implementierungen die ich kenne, wahrscheinlich gehen irgendwelche Programme davon aus.

Gast
2006-01-19, 21:08:30
Hab hier kein Compiler, aber http://www.delorie.com/djgpp/compile/ macht es nicht so! Wenn ich nacher was zu essen hol kann ich mal an meinen Linux PC... Bin abet ATM zu faul zum aufstehn :>

Coda
2006-01-19, 21:31:00
Gut. Du hast auf jedenfall recht, ich hatte es falsch in Erinnerung, wahrscheinlich aus dem Grund, dass die Standard-Libs die ich kenne -1, 0 und 1 ausspucken.

Aber wie gesagt, du hast Recht, in der Dokumentation steht nur <0 0 und >0. Mit der Implementierung sparst du einen Branch, das ist gar nicht schlecht.

Gast
2006-01-19, 22:06:30
Da hat mir jemand (www.google.com) geholfen bei dir... man muss ja net immer das Rad neu erfinden

PatTheMav
2006-01-20, 00:05:18
int strcmp(const char *str1, const char *str2) {
if (str1 == NULL)
return 1;
else if (str2 == NULL)
return -1;
else if (str2 == NULL && str1 == NULL)
return 0;

while (str1 != '\0' && str2 != '\0') {
if (str1++ == str2++)
continue;
else
break;
}

return (str1 == str2) ? 0 : (str1 < str2) ? -1 : 1;
}
Sollte es eigentlich tun, meine C-Zeit ist schon länger her :)

Damit prüfst du aber auf jedenfall Fehlerfälle (Pointer auf NULL) ab und bekommst halt nur -1,0,1 als Return Codes.

Wobei ich mir nicht mehr sicher bin, ob im Code auch "*" stehen muss, soweit ich das sehe, wär das dann pointer auf pointer aber wir wollen ja nur die chars, also reicht der einfacher pointer in meinen Augen.

Coda
2006-01-20, 00:24:23
Damit prüfst du aber auf jedenfall Fehlerfälle (Pointer auf NULL) ab und bekommst halt nur -1,0,1 als Return Codes.Das muss die Funktion nicht. Defensives Programmieren ist hier fehl am Platz imho.

Neomi
2006-01-20, 01:01:06
if (str1 == NULL)
return 1;
else if (str2 == NULL)
return -1;
else if (str2 == NULL && str1 == NULL)
return 0;


Dieser Teil der Funktion wird NIEMALS 0 zurückliefern. Wenn du die Abfragen wirklich drin haben willst, solltest du die letzte Abfrage (beide NULL) als erstes ausführen. Ich vermute auch mal, daß der nicht existierende String der "kleinere" sein soll, also einmal -1 und 1 vertauscht. Noch ein klein wenig optimiert sähe das so aus:


if (str1 == str2) // gilt für beide NULL und weitere Fälle
return 0;
else if (str1 == NULL)
return -1;
else if (str2 == NULL)
return 1;

Xmas
2006-01-20, 02:16:46
int strcmp(const char *str1, const char *str2)
{
while (*str1 == *str2 && *str1 != '\0' )
++str1, ++str2;
return *str1 - *str2;
}

Das _IST_ es! (wie man so schön sagt: possible implementation)
Korrektur:
int strcmp(const char *s1, const char *s2)
{
while (*s1 == *s2 && *s1 != '\0' )
++s1, ++s2;
return (unsigned char)*s1 - (unsigned char)*s2;
}
strcmp vergleicht unsigned.

Coda
2006-01-20, 02:31:05
Hm ne, das soll ja <0 zurückliefern wenn *s1 kleiner als *s2 ist. an dieser Stelle ist einer der beiden ja schon 0, also ist das Ergebnis entweder größer oder kleiner Null.

Wieso willst du das unsigned machen?

Neomi
2006-01-20, 02:48:24
Wieso willst du das unsigned machen?

Weil beim signed char die ANSI-Zeichen 128 bis 255 als -128 bis -1 gewertet werden. Das Ergebnis ist dann logischerweise falsch herum.

Xmas
2006-01-20, 02:50:14
Hm ne, das soll ja <0 zurückliefern wenn *s1 kleiner als *s2 ist. an dieser Stelle ist einer der beiden ja schon 0, also ist das Ergebnis entweder größer oder kleiner Null.
Bitte?
Die Schleife bricht ab wenn sich die Strings unterscheiden ODER der erste String endet (wenn der zweite vor dem ersten endet, unterscheiden sie sich ja dort, somit ist schon die erste Abbruchbedingung erfüllt).
Die beiden Zeichen können nach der Schleife entweder unterschiedlich oder beide gleich Null sein (letzteres bei identischen Strings). Sind sie Unterschiedlich, so ist s1 - s2 dann kleiner Null wenn s1 kleiner s2 ist, also genau das Ergebnis was man auch von strcmp erwartet.

Wieso willst du das unsigned machen?
Weil das vom C-Standard so vorgesehen ist. Aus drei Gründen:
- damit '\0' vor allen anderen Zeichen kommt (kurze Strings zuerst)
- damit alle Sonderzeichen >127 aufsteigend
- und nach den ASCII-Buchstaben und Zahlen sortiert werden.

Vergleichst du signed char, so ist '\x80' < '\0'

edit: sorry, hatte vergessen dass \000 oktal ist, nicht dezimal. Grund 2 ist natürlich auch Blödsinn, aufsteigend sind sie auch so, weil 0x80 als signed char die kleinste Zahl ist.

N!mrod
2006-01-20, 09:49:07
Moin!

Thx für eure Hilfe, ich hatte aber noch keine Zeit eine Funktion zu testen.
Da sich jetz hier einige Funktionen angesammelt haben, wäre es nett wenn mir jemand sagen könnte welche davon funktionstüchtig ist, bzw. welche von denen ich verwenden soll,.. ;)

mithrandir
2006-01-20, 11:44:05
Wie wär's erstmal mit "verstehen", dann selbst nachimplementieren? Ich sehe nicht, dass du dir auch nur die geringste Mühe machst, die Funktionen hier zu verstehen. Eigentlich solltest du ja selbst eine schreiben, nicht von anderen eine schreiben lassen, denk ich mal.

N!mrod
2006-01-20, 11:58:54
k, habs eh schon. Trotzdem thx! Und btw: Ich habs auch verstanden. =)

Coda
2006-01-20, 13:14:07
Bitte?
Die Schleife bricht ab wenn sich die Strings unterscheiden ODER der erste String endet (wenn der zweite vor dem ersten endet, unterscheiden sie sich ja dort, somit ist schon die erste Abbruchbedingung erfüllt).
Die beiden Zeichen können nach der Schleife entweder unterschiedlich oder beide gleich Null sein (letzteres bei identischen Strings). Sind sie Unterschiedlich, so ist s1 - s2 dann kleiner Null wenn s1 kleiner s2 ist, also genau das Ergebnis was man auch von strcmp erwartet.Ja wir meinen das gleiche.

Das Ding funktioniert aber auch ohne den Cast - probiers aus.

Xmas
2006-01-20, 14:44:39
Ach ja? Rate mal was hierbei rauskommt:

#include <stdio.h>

int strcmp1(const char *str1, const char *str2)
{
while (*str1 == *str2 && *str1 != '\0' )
++str1, ++str2;
return *str1 - *str2;
}

int strcmp2(const char *str1, const char *str2)
{
while (*str1 == *str2 && *str1 != '\0' )
++str1, ++str2;
return (unsigned char)*str1 - (unsigned char)*str2;
}

int main()
{
printf("%d, ", strcmp1("abc\x7f", "abc\x80"));
printf("%d ", strcmp2("abc\x7f", "abc\x80"));
getch();
}

Genau:
255, -1