J'ai essayé d'implémenter strcmp
:
int strCmp(char string1[], char string2[] )
{
int i=0,flag=0;
while(flag==0)
{
if (string1[i]>string2[i])
{
flag=1;
}
else if (string1[i]<string2[i])
{
flag=-1;
}
else
{
i++;
}
}
return flag;
}
mais je suis coincé avec le cas où l'utilisateur saisira les mêmes chaînes, car 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 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 string1[], char string2[] )
{
int i = 0;
int flag = 0;
while (flag == 0)
{
if (string1[i] > string2[i])
{
flag = 1;
}
else if (string1[i] < string2[i])
{
flag = -1;
}
if (string1[i] == '\0')
{
break;
}
i++;
}
return flag;
}
Une version plus courte:
int strCmp(char string1[], char string2[] )
{
for (int i = 0; ; i++)
{
if (string1[i] != string2[i])
{
return string1[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, indexer un tableau est en utilisant 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 paramètres doivent être des pointeurs sur les chaînes constantes pour permettre la comparaison également pour les 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 (GCC est supposé)
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 comparer les autres https://godbolt.org/g/ZbMmYM
Tiré de ici .
#include<stdio.h>
#include<string.h>
//using arrays , need to move the string 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
.
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;
}
retourne des valeurs
-1 // <0
1 // >0
0 // ==0
La dernière opération ternaire est optionnel
La fonction serait toujours dans les règles de strcmp
lorsque vous retournerez simplement *s1 - *s2
.
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 && (string1[i] != 0 | string2[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 des caractères peut ne pas donner le résultat escompté. Pour l'un, il n'est pas défini si char
est signé ou non signé, vous devriez donc probablement transtyper en unsigned char
pour la comparaison.
Une solution plus propre consisterait peut-être à revenir immédiatement lorsque vous détectez la différence, c’est-à-dire que, au lieu de flag = -1
, vous renvoyez directement -1
. Mais c'est plus une question d'opinion.