XV. c_strncmp▲
XV-A. Prototype▲
int
c_strncmp (
const
char
*
s1, const
char
*
s2, c_size_t n);
XV-B. Description et comportement▲
La fonction c_strncmp compare deux chaînes de caractères
sur une longueur n, le caractère nul participe à la
comparaison et par conséquent, une chaîne possédant ce caractère
sera inférieure à l'autre !
La fonction renvoie trois valeurs suivant des cas précis:
- Valeur négative si la chaîne d'adresse s1 est inférieure à la chaîne d'adresse s2.
- Zéro si les deux chaînes de caractères sont identiques.
- Valeur positive si la chaîne d'adresse s1 est supérieure à la chaîne d'adresse s2.
La norme du C ne précise cependant pas quelle est la valeur renvoyée. Dans certaines implémentations comme sur Linux et Windows par exemple, cette fonction renvoie les valeurs -1, 0, 1 mais dans d'autres implémentations cette fonction peut directement retourner le résultat de la soustraction des deux octets différents !
La comparaison des octets se fait par conversion du type void * en un type unsigned char * !
XV-C. Algorithme▲
Voici un algorithme possible pour la fonction c_strncmp:
algorithme
fonction c_strcmp (s1:chaîne, s2:chaîne, n:entier):entier
début
i <- 0
tant que n <- n - 1 faire
si s1[i] égal à 0 ou s1[i] différent de s2[i] alors
si s1[i] inférieur à s2[i]
alors retourne -1
sinon retourne 1
fsi
fsi
i <- i + 1
ftant
retourne 0
fin
lexique
s1 : chaîne : Chaîne de caractères pour la comparaison avec la chaîne s2.
s2 : chaîne : Chaîne de caractères pour la comparaison.
n : Longueur de la comparaison.
i : Variable d'incrémentation pour le parcours des adresses mémoire.
La boucle parcourt les adresses depuis leur point de départ jusqu'à
n. Dans la première condition nous testons si l'octet courant
de la chaîne s1 est un caractère nul ou si les deux
octets courants sont différents. Si les deux octets courants sont
différents, nous testons leur différence et nous retournons la
valeur adéquate.
Nous pouvons voir qu'ici je n'ai pas choisi de retourner comme
valeur le résultat d'une soustraction entre les deux octets mais
uniquement une valeur relative au bit du signe du résultat comme
le font la plupart des implémentations ! Si l'octet pointé par
l'adresse s1[i] et inférieur à celui de l'adresse s2[i]
nous retournons la valeur -1, 1 sinon.
Si la boucle se termine, c'est la valeur 0 qui est
retournée car dans ce cas le contenu des deux adresses est
identique !
Complexité temporelle dans le pire des cas: |
---|
Dans le pire des cas, c'est à dire une égalité parfaite: complexité en O(taille(s1/2)) |
XV-D. Implémentation▲
int
c_strncmp (
const
char
*
s1, const
char
*
s2, c_size_t n)
{
const
unsigned
char
*
p_s1 =
s1;
const
unsigned
char
*
p_s2 =
s2;
while
(
n--
)
{
if
(*
p_s1 ==
0
||
*
p_s1 !=
*
p_s2)
{
return
*
p_s1 <
*
p_s2 ? -
1
: 1
;
}
p_s1++
;
p_s2++
;
}
return
0
;
}
Comme précisé dans la description de la fonction, la comparaison
se fait par conversion en type unsigned char,
c'est ce que nous faisons dans cette implémentation en faisant
pointer les deux adresses par des pointeurs de ce type !
A chaque tour de boucle nous incrémentons également les deux
pointeurs p_s1 et p_s2 pour avancer sur l'octet
suivant des deux chaînes de caractères !
XV-E. Tests▲
#include "c_string.h"
#include <stdio.h>
int
main (
void
)
{
char
*
str1 =
"
abcdefghij
"
;
char
*
str2 =
"
abcdefghij
"
;
char
*
str3 =
"
abcefghijk
"
;
char
*
str4 =
"
abbcdefghi
"
;
printf (
"
Test 1 : %d
\n
"
, c_strncmp (
str1, str2, 4
));
printf (
"
Test 2 : %d
\n
"
, c_strncmp (
str2, str3, 4
));
printf (
"
Test 3 : %d
\n
"
, c_strncmp (
str3, str4, 4
));
return
0
;
}
Dans ce programme de test nous faisons trois comparaisons pour vérifier tous les points de la fonction c_strncmp. Nous commençons par un test d'égalité, un test d'infériorité puis pour finir un test de supériorité ! Voici ce que cela donne en sortie sur la console :
Test 1 : 0
Test 2 : -1
Test 3 : 1
Process returned 0 (0x0) execution time : 0.015 s
Press any key to continue.