Implémentation de strcmp

J’ai essayé d’implémenter strcmp :

 int strCmp(char ssortingng1[], char ssortingng2[] ) { int i=0,flag=0; while(flag==0) { if (ssortingng1[i]>ssortingng2[i]) { flag=1; } else if (ssortingng1[i]<string2[i]) { flag=-1; } else { i++; } } return flag; } 

mais je suis coincé avec le cas où l’utilisateur entrera les mêmes chaînes, parce que la fonction fonctionne avec 1 et -1, mais ne renvoie pas 0. Quelqu’un peut-il aider? Et s’il vous plaît sans pointeurs!

Vous semblez vouloir éviter les arithmétiques de pointeur, ce qui est dommage car cela raccourcit la solution, mais votre problème est simplement que vous balayez au-delà de la fin des chaînes. Ajouter une pause explicite fonctionnera. Votre programme légèrement modifié:

 int strCmp(char ssortingng1[], char ssortingng2[] ) { int i = 0; int flag = 0; while (flag == 0) { if (ssortingng1[i] > ssortingng2[i]) { flag = 1; } else if (ssortingng1[i] < string2[i]) { flag = -1; } if (string1[i] == '\0') { break; } i++; } return flag; } 

Une version plus courte:

 int strCmp(char ssortingng1[], char ssortingng2[] ) { for (int i = 0; ; i++) { if (ssortingng1[i] != ssortingng2[i]) { return ssortingng1[i] < string2[i] ? -1 : 1; } if (string1[i] == '\0') { return 0; } } } 

Uhm .. beaucoup trop compliquer. Allez pour celui-ci:

 int strCmp(const char* s1, const char* s2) { while(*s1 && (*s1 == *s2)) { s1++; s2++; } return *(const unsigned char*)s1 - *(const unsigned char*)s2; } 

Il retourne <0, 0 ou> 0 comme prévu

Vous ne pouvez pas le faire sans pointeurs. En C, l’indexation d’un tableau utilise des pointeurs.

Peut-être voulez-vous éviter d’utiliser l’opérateur * ? 🙂

Tout d’abord, la fonction C standard strcmp compare les éléments de chaînes avec le type unsigned char .

Deuxièmement, les parameters doivent être des pointeurs sur les chaînes constantes pour permettre également la comparaison des chaînes constantes.

La fonction peut être écrite de la manière suivante

 int strCmp( const char *s1, const char *s2 ) { const unsigned char *p1 = ( const unsigned char * )s1; const unsigned char *p2 = ( const unsigned char * )s2; while ( *p1 && *p1 == *p2 ) ++p1, ++p2; return ( *p1 > *p2 ) - ( *p2 > *p1 ); } 

Ceci est une implémentation de 10 opcodes de strcmp (supposé GCC)

 int strcmp_refactored(const char *s1, const char *s2) { while (1) { int res = ((*s1 == 0) || (*s1 != *s2)); if (__builtin_expect((res),0)) { break; } ++s1; ++s2; } return (*s1 - *s2); } 

Vous pouvez essayer cette implémentation et la comparer aux autres https://godbolt.org/g/ZbMmYM

Pris d’ ici .

 #include #include //using arrays , need to move the ssortingng using index int strcmp_arry(char *src1, char *src2) { int i=0; while((src1[i]!='\0') || (src2[i]!='\0')) { if(src1[i] > src2[i]) return 1; if(src1[i] < src2[i]) return 1; i++; } return 0; } //using pointers, need to move the position of the pointer int strcmp_ptr(char *src1, char *src2) { int i=0; while((*src1!='\0') || (*src2!='\0')) { if(*src1 > *src2) return 1; if(*src1 < *src2) return 1; src1++; src2++; } return 0; } int main(void) { char amessage[] = "string"; char bmessage[] = "string1"; printf(" value is %d\n",strcmp_arry(amessage,bmessage)); printf(" value is %d\n",strcmp_ptr(amessage,bmessage)); } 

J'ai apporté quelques modifications pour que cela fonctionne comme strcmp .

Votre problème est que vous ne détectez pas la fin de la chaîne et ne renvoyez donc pas zéro si les deux chaînes se terminent avant que toute différence ne soit détectée.

Vous pouvez simplement résoudre ce problème en recherchant ceci dans la condition de boucle:

 while( flag==0 && (ssortingng1[i] != 0 | ssortingng2[i] != 0 ) ) 

Notez que les deux chaînes sont vérifiées, car si une seule est à la fin, les chaînes ne sont pas égales et la comparaison à l’intérieur de la boucle devrait le détecter.

Veuillez noter que la comparaison de caractères peut ne pas donner le résultat escompté. D’une part, il n’est pas défini si char est signé ou non, vous devriez donc probablement transtyper en caractère unsigned char pour la comparaison.

Peut-être qu’une solution plus propre consisterait à retourner immédiatement lorsque vous détectez la différence, c’est-à-dire au lieu de flag = -1 vous retournerez directement -1 . Mais c’est plus une question d’opinion.

Ma mise en œuvre

 int strcmp(const char * s1, const char * s2) { while (*s1 == *s2 && *s1++ | *s2++); int i = *s1 - *s2; return i < 0 ? -1 : i > 0 ? 1 : 0; } 

renvoyer des valeurs

 -1 // <0 1 // >0 0 // ==0 

La dernière opération ternaire est optionnelle

La fonction serait toujours dans les règles de strcmp lorsque vous retournerez *s1 - *s2 .