Comment fonctionne strcmp ()?

J’ai cherché pas mal de réponses. Je vais créer une série de mes propres fonctions de chaîne, telles que my_strcmp() , my_strcat() , etc.

strcmp() fonctionne-t-il sur chaque index de deux tableaux de caractères et si la valeur ASCII est plus petite à un index identique de deux chaînes, cette chaîne y est alphabétiquement supérieure et donc 0 ou 1 ou 2 est renvoyé? Je suppose que ce que je demande, est-ce qu’il utilise les valeurs ASCII des caractères pour renvoyer ces résultats?

Toute aide serait grandement appréciée.

[MODIFIÉ]

OK, donc je suis venu avec cela … cela fonctionne dans tous les cas, sauf lorsque la deuxième chaîne est supérieure à la première.

Des conseils?

 int my_strcmp(char s1[], char s2[]) { int i = 0; while ( s1[i] != '\0' ) { if( s2[i] == '\0' ) { return 1; } else if( s1[i]  s2[i] ) { return 1; } i++; } return 0; } int main (int argc, char *argv[]) { int result = my_strcmp(argv[1], argv[2]); printf("Value: %d \n", result); return 0; } 

Le pseudo-code “implementation” de strcmp ressemblerait à quelque chose comme:

 define strcmp (s1, s2): p1 = address of first character of str1 p2 = address of first character of str2 while contents of p1 not equal to null: if contents of p2 equal to null: return 1 if contents of p2 greater than contents of p1: return -1 if contents of p1 greater than contents of p2: return 1 advance p1 advance p2 if contents of p2 not equal to null: return -1 return 0 

C’est fondamentalement ça. Chaque caractère est comparé à son tour. Il est ensuite décidé si la première ou la deuxième chaîne est plus grande, en fonction de ce caractère.

Vous ne passez au caractère suivant que si les caractères sont identiques et, si tous les caractères sont identiques, zéro est renvoyé.

Notez que vous ne pouvez pas nécessairement obtenir 1 et -1, les spécifications spécifient que toute valeur positive ou négative suffira. Vous devez donc toujours vérifier la valeur de retour avec < 0 , > 0 ou == 0 .

Transformer cela en vrai C serait relativement simple:

 int myStrCmp (const char *s1, const char *s2) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; while (*p1 != '\0') { if (*p2 == '\0') return 1; if (*p2 > *p1) return -1; if (*p1 > *p2) return 1; p1++; p2++; } if (*p2 != '\0') return -1; return 0; } 

N'oubliez pas non plus que "supérieur" dans le contexte des caractères ne repose pas nécessairement sur un simple classement ASCII pour toutes les fonctions de chaîne.

C a un concept appelé "locales" qui spécifie (entre autres) un classement ou un ordre du jeu de caractères sous-jacent et vous pouvez constater, par exemple, que les caractères a , á , à et ä sont tous considérés comme identiques. Cela se produira pour des fonctions comme strcoll .

Voici l’ implémentation de BSD :

 int strcmp(s1, s2) register const char *s1, *s2; { while (*s1 == *s2++) if (*s1++ == 0) return (0); return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); } 

Une fois qu’il y a une discordance entre deux caractères, la différence entre ces deux caractères est simplement renvoyée.

Il utilise les valeurs d’octet des caractères et renvoie une valeur négative si la première chaîne apparaît avant la seconde (classée par valeurs d’octets), zéro si elles sont égales et une valeur positive si la première apparaît après la seconde. Comme il fonctionne sur des octets, il n’est pas sensible au codage.

Par exemple:

 strcmp("abc", "def") < 0 strcmp("abc", "abcd") < 0 // null character is less than 'd' strcmp("abc", "ABC") > 0 // 'a' > 'A' in ASCII strcmp("abc", "abc") == 0 

Plus précisément, comme décrit dans la spécification strcmp Open Group :

Le signe d’une valeur de retour non nulle doit être déterminé par le signe de la différence entre les valeurs de la première paire d’octets (interprétées toutes les deux comme des caractères de type unsigned), qui diffèrent par les chaînes comparées.

Notez que la valeur de retour peut ne pas être égale à cette différence, mais elle portera le même signe.

Ceci, des maîtres eux-mêmes ( K & R , 2e éd., P. 106):

 // 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]; } 

Voici ma version, écrite pour les petites applications de microcontrôleur, compatible MISRA-C. L’objective principal de ce code était d’écrire du code lisible, au lieu de l’arbre à une ligne trouvé dans la plupart des bibliothèques de compilation.

 int8_t strcmp (const uint8_t* s1, const uint8_t* s2) { while ( (*s1 != '\0') && (*s1 == *s2) ) { s1++; s2++; } return (int8_t)( (int16_t)*s1 - (int16_t)*s2 ); } 

Remarque: le code suppose un type int 16 bits.

Ce code est équivalent, plus court et plus lisible:

 int8_t strcmp (const uint8_t* s1, const uint8_t* s2) { while( (*s1!='\0') && (*s1==*s2) ){ s1++; s2++; } return (int8_t)*s1 - (int8_t)*s2; } 

Nous avons seulement besoin de tester la fin de s1, car si nous atteignons la fin de s2 avant la fin de s1, la boucle se terminera (puisque * s2! = * S1).

L’expression de retour calcule la valeur correcte dans tous les cas, à condition que nous n’utilisions que des caractères de 7 bits (ASCII pur). Il faut bien réfléchir pour produire le code correct pour les caractères 8 bits, en raison du risque de dépassement d’entier.

J’ai trouvé ceci sur le web.

http://www.opensource.apple.com/source/Libc/Libc-262/ppc/gen/strcmp.c

 int strcmp(const char *s1, const char *s2) { for ( ; *s1 == *s2; s1++, s2++) if (*s1 == '\0') return 0; return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1); } 

Voici comment j’ai implémenté mon strcmp: cela fonctionne comme ceci: il compare la première lettre des deux chaînes, si elle est identique, continue à la lettre suivante. Sinon, il retourne la valeur correspondante. C’est très simple et facile à comprendre: #include

 //function declaration: int strcmp(char ssortingng1[], char ssortingng2[]); int main() { char ssortingng1[]=" The San Antonio spurs"; char ssortingng2[]=" will be champins again!"; //calling the function- strcmp printf("\n number returned by the strcmp function: %d", strcmp(ssortingng1, ssortingng2)); getch(); return(0); } /**This function calculates the dictionary value of the ssortingng and compares it to another ssortingng. it returns a number bigger than 0 if the first ssortingng is bigger than the second it returns a number smaller than 0 if the second ssortingng is bigger than the first input: ssortingng1, ssortingng2 output: value- can be 1, 0 or -1 according to the case*/ int strcmp(char ssortingng1[], char ssortingng2[]) { int i=0; int value=2; //this initialization value could be any number but the numbers that can be returned by the function while(value==2) { if (ssortingng1[i]>ssortingng2[i]) { value=1; } else if (ssortingng1[i] 

Est-ce juste ceci:

 int strcmp(char *str1, char *str2){ while( (*str1 == *str2) && (*str1 != 0) ){ ++*str1; ++*str2; } return (*str1-*str2); } 

si vous voulez plus vite, vous pouvez append “register” avant le type, comme ceci: register char

alors, comme ceci:

 int strcmp(register char *str1, register char *str2){ while( (*str1 == *str2) && (*str1 != 0) ){ ++*str1; ++*str2; } return (*str1-*str2); } 

De cette façon, si possible, le registre de l’ALU est utilisé.