IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Étude détaillée du module String de la libc


précédentsommairesuivant

XV. c_strncmp

XV-A. Prototype

 
Sélectionnez
int c_strncmp (const char * s1, const char * s2, c_size_t n);

XV-B. Description et comportement

La fonction c_strncmp compare deux chaines de caractères sur une longueur n, le caractère nul participe à la comparaison et par conséquent, une chaine 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 chaine d'adresse s1 est inférieure à la chaine d'adresse s2 ;
  • Zéro si les deux chaines de caractères sont identiques ;
  • Valeur positive si la chaine d'adresse s1 est supérieure à la chaine 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 :

 
Sélectionnez
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 : chaine : Chaine de caractères pour la comparaison avec la chaine s2.
   s2 : chaine : Chaine 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 chaine 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

 
Sélectionnez
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 !

À chaque tour de boucle, nous incrémentons également les deux pointeurs p_s1 et p_s2 pour avancer sur l'octet suivant des deux chaines de caractères !

XV-E. Tests

 
Sélectionnez
#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 :

 
Sélectionnez
Test 1 : 0
Test 2 : -1
Test 3 : 1
 
Process returned 0 (0x0)   execution time : 0.015 s
Press any key to continue.

précédentsommairesuivant

Copyright © 2007 Franck Hecht. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.