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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

comparaison strcmp de void *


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    valkheim
    Invité(e)
    Par défaut comparaison strcmp de void *
    Bonjour,

    J'ai deux void * que je voudrais comparer à la manière d'un strcmp.
    J'y arrive avec des char * mais je n'y parviens pas en envoyant des void * ou en castant mes char * pour du void *

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    int     cmp_w_str(char *s1, char *s2)
    {
      int   i;
     
      i = 0;
      while (s1[i] != '\0')
        {
          if (s1[i] < s2[i])
            return (-1);
          if (s1[i] > s2[i])
            return (1);
          i++;
        }
      return (0);
    }
    Ci dessus ma fonction à la strcmp qui compare mes deux char *

    Comment peut-on le réaliser avec des void * passés en paramètres ?
    Peut on le faire en castant les void * pour du char * ?

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Tu ne peux pas comparer autre chose que des chaînes de caractères avec une fonction ne prenant que des pointeurs en paramètre, car tu ne sauras pas où t'arrêter!

    une bonne fonction de comparaison aura un prototype de ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int voidcmp(const void *a, const void*b, size_t size)
    {
    Voire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int voidcmp(const void *a, const void*b, size_t sizeA, size_t sizeB)
    {
    Ensuite pour la comparaison elle-même, il vaudra convertir en unsigned char const * pour obtenir les bytes pointés, vu qu'on ne peut pas déréférencer un void*.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par valkheim Voir le message
    J'ai deux void * que je voudrais comparer à la manière d'un strcmp.
    J'y arrive avec des char * mais je n'y parviens pas en envoyant des void * ou en castant mes char * pour du void *

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    int     cmp_w_str(char *s1, char *s2)
    {
      int   i;
     
      i = 0;
      while (s1[i] != '\0')
        {
          if (s1[i] < s2[i])
            return (-1);
          if (s1[i] > s2[i])
            return (1);
          i++;
        }
      return (0);
    }
    Comment peut-on le réaliser avec des void * passés en paramètres ?
    Peut on le faire en castant les void * pour du char * ?
    Bonjour

    Déjà tu as un comportement indéterminé si s2 est plus petite (en terme de longueur de chaine) que s1 car dans ce cas là, tu tapes au delà de sa plage légale.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int	 cmp_w_str(char *s1, char *s2)
    {
    	char *pt1=s1;
    	char *pt2=s2;
     
    	do {
    		if (*pt1 < *pt2) return -1;
    		if (*pt1 > *pt2) return 1;
    	} while (*pt1++ && *pt2++);
    	return 0;
    }
    En ce qui concerne ton pb de void*, te suffit de caster tes void* en char* lors de l'appel
    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void *xxx;
    void *yyy;
    cmp_w_str(char*)xxx, (char*)yyy);
    En considérant bien entendu que ces pointeurs "void" pointent quand-même vers des suites de caractère contenant un '\0'.

    Si maintenant tu veux écrire une fonction acceptant des void* (cela semble étrange pour une telle fonction sensée manipuler ce qu'elle reçoit comme du caractère), alors il te suffit d'écrire son début ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int     cmp_w_str(void *s1, void *s2)
    {
        char *pt1=(char*)s1;
        char *pt2=(char*)s2;
        ... (le reste sans changement)...
    }
    PS: je ne suis pas certain que le cast soit obligatoire (ça dépend des options de compilation)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    valkheim
    Invité(e)
    Par défaut
    Merci pour vos réponses

    La comparaison fonctionne désormais bien avec mes void *
    Pourtant j'ai quelques problèmes avec la longueur. Il fonctionne bien aux tests unitaires mais pas quand j'essaie de boucler l'affaire :/
    Je m'explique : j'ai deux listes contenant des nombres dans des void * à trier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    int     voidcmp(const void *a, const void *b)
    {
      unsigned char const *s1 = a;
      unsigned char const *s2 = b;
      int   i;
     
      i = 0;
      if (my_strlen(s1) < my_strlen(s2))
        return (-1);
      else
        while (s1[i] != '\0')
          {
            if (s1[i] < s2[i])
              return (-1);
            if (s1[i] > s2[i])
              return (1);
            i++;
          }
      return (0);
    }
    Voici ma fonction de comparaison avec les void *, elle fonctionne bien il me semble.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    int     bubble(t_dllist **head_a, t_dllist **head_\
    b)
    {
      t_dllist      *current_a;
      t_dllist      *current_b;
      char          *small;
      int           index;
     
      current_a = *head_a;
      current_b = *head_b;
     
      if (current_a == NULL)
        return (0);
      small = smallest_of(head_a);
      index = smallest_of_index(&current_a, small);
      while (index > 0)
        {
          rotate_a(&current_a);
          index--;
        }
      put_in_b(head_a, head_b);
      bubble(head_a, head_b);
    }
    Ici j'effectue mon tri. Il fonctione avec des chiffres mais me renvoie un mauvais placement pour les nombres supérieurs ou égaux à 10.
    Cette fonction prend deux listes a et b en paramètres. Elle parcours la liste a en trouvant le plus petit élément (smallest of a)
    Elle va ensuite récupérer l'indice du plus petit élément.
    Elle effectue u rotate vers la gauche de la liste a jusqu'à ce qu'il soit au début. Le rôle de put_in_b est ensuite de faire passer le premier élément de a (le plus petit) dans la liste b. Elle le place au début.
    Je fais enfin "boucler" le tout jusqu'à ce que ma liste a soit vide.

    Ex :

    Entrée
    liste_a :: 2:1:3:6:5:8:
    liste_b ::

    Sortie
    liste_a ::
    liste_b :: 8:6:5:3:2:1

    Et avec des nombres plus grands que 9

    Entrée
    liste_a :: 2:10:3:6:5:8:
    liste_b ::

    Sortie
    liste_a ::
    liste_b :: 8:5:6:3:10:2:

    Comment arranger celà ? :/
    J'ai l'impression qu'il ne s'agit que d'une ou plusieurs erreurs de parcours de liste..

    EDIT2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    int     voidcmp(const void *a, const void *b)
    {
      unsigned char const *s1 = a;
      unsigned char const *s2 = b;
      int   i;
     
      i = -1;
      if (my_strlen(s1) < my_strlen(s2))
        return (-1);
      else
        if (my_strlen(s1) > my_strlen(s2))
          return (1);
      else
        while (s1[++i] != '\0')
          if (s1[i] < s2[i])
            return (-1);
          else if (s1[i] > s2[i])
            return (1);
      return (0);
    }
    Dernière modification par valkheim ; 14/11/2015 à 18h27.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par valkheim Voir le message
    Ici j'effectue mon tri. Il fonctione avec des chiffres mais me renvoie un mauvais placement pour les nombres supérieurs ou égaux à 10.
    Entrée
    liste_a :: 2:10:3:6:5:8:
    liste_b ::

    Sortie
    liste_a ::
    liste_b :: 8:5:6:3:10:2:

    J'ai l'impression qu'il ne s'agit que d'une ou plusieurs erreurs de parcours de liste..
    Non, c'est plutôt qu'en comparaison alphabétique (ce que fait strlen), 1 ('1', '\0') est plus petit que 10 ('1', '0', '\0') et lui-même est plus petit que 2 ('2', '\0')...
    Ben oui, la comparaison se fait caractère par caractère. Or quand il compare 10 et 2, il commence par comparer '1' et '2' et là, ben il s'arrête...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    valkheim
    Invité(e)
    Par défaut
    Oui tout à fait.
    Le problème a été fixé en rajoutant le retour 1 si s2 était plus longue que s1.
    Je ne considérais jusqu'alors pas la rotation des éléments dans ma liste et j'avais donc ommis ce cas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Copie de l'identifiant et du mot de passe pour comparaison (strcmp)
    Par jimmysoft dans le forum GTK+ avec C & C++
    Réponses: 4
    Dernier message: 23/06/2011, 12h02
  2. probleme de comparaison avec strcmp
    Par wolverine1987 dans le forum Visual C++
    Réponses: 20
    Dernier message: 18/06/2009, 11h48
  3. problem de comparaison strcmp()
    Par ostie127 dans le forum Débuter
    Réponses: 8
    Dernier message: 16/02/2008, 10h47
  4. strcmp( void * , "\n" )
    Par v4np13 dans le forum C
    Réponses: 4
    Dernier message: 18/03/2007, 11h25
  5. comparaison avec strcmp
    Par je®ome dans le forum C
    Réponses: 9
    Dernier message: 23/05/2006, 18h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo