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 :

memcmp et caracteres


Sujet :

C

  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 849
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 849
    Par défaut memcmp et caracteres
    bonjour,

    a l'aide de memcomp, je voudrais tester si un tableau a une certaine valeur. Actuellement, je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(memcmp(myTab, "\x01\x02\x03", 3) != 0)
    => comment définir la chaine de comparaison sans avoir le caractère '\0' en fin de chaine (car actuellement, ça me bouffe un caractère pour rien)

    j'ai essayé ça mais ça ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(memcmp(myTab, {0x01, 0x02, 0x03}, 3) != 0)
    merci d'avance

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    pour comparer des chaînes, c'est strcmp

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    => comment définir la chaine de comparaison sans avoir le caractère '\0' en fin de chaine (car actuellement, ça me bouffe un caractère pour rien)
    Par définition, une chaine de caractères se termine par '\0'. Sinon, ce n'est pas une chaine de caractères.
    Comment la fonction est-elle censée savoir quel est le dernier élément d'un tableau si on ne lui précise pas où il se termine ? D'où le '\0' pour terminer les chaînes.

    Si tu veux comparer un tableau de caractères sans t'occuper du '\0' final, AMHA il n'y a pas d'autre solution que de préciser à la fonction le nombre de caractères à tester, soit en codant ta propre fonction soit en utilisant par exemple strncmp. (le n indiquant les n premiers éléments de la 1ere chaine à tester)
    Pour le tableau qui servira à comparer, il suffit de déclarer et d'initialiser comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char tableau[] = { 0x01 , 0x02 , 0x03 } ;
    Car si tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char tableau[] = "\x01\x02\x03" ;
    le '\0' sera automatiquement rajouté à la fin car il s'agit d'une chaine littérale (et comme dans toute chaine, cela se termine par '\0').

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 849
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 849
    Par défaut
    ma fonction memcmp() à trois paramètres au cas où vous ne l'auriez pas remarqué : et devinez à quoi sert le 3ième paramètres ? ... à définir la taille de la variable

    donc ma question est en fait comment faire pour faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char pattern[3] = { 0x01 , 0x02 , 0x03 } ;
    if(memcmp(myTab, pattern, 3) != 0)
    ... en ne créant pas le tableau pattern (existe t-il en C une écriture qui permet de définir directement les valeurs) ?

    => j'ai essayé de mettre directement mes valeurs sous la même forme que l'initialisation d'un tableau mais ça ne compile pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(memcmp(myTab, { 0x01 , 0x02 , 0x03 }, 3) != 0)

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    myTab[0] = 0x01 ;
    myTab[1] = 0x02 ;
    myTab[2] = 0x03 ;
    Mais j'avoue avoir du mal à comprendre ce que tu veux faire, si ce n'est re-programmer un memcmp..


    Sinon, tu peux toujours faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcmp ( MyTab, "0x010x020x03", 3 )
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcmp ( MyTab, "\x01\x02\x03", 3 )
    et en déclarant comme char * ton pattern.

    Mais je ne vois pas ton problème avec le "\0", qui est transparent de toutes façons..

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 849
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 849
    Par défaut
    ce que je veux faire c'est juste ne pas utiliser des ressources inutilement (sur un système embarqué c'est toujours utile de gagné de la place, on en manque toujours) et éviter que mon code prenne plusieurs lignes pour rien => je veux juste savoir si on peut simplifier mon exemple (c'est peut-être impossible)

  7. #7
    Membre confirmé Avatar de Gui13
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Par défaut
    C'est impossible syntaxiquement, et de toute façon tu t'y retrouveras quand même au niveau mémoire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char pattern[] = { 0x1, 0x2, 0x3};
    memcmp( mon_tableau, pattern, 3);

    occupe la même place en mémoire qu'un syntaxiquement incorrect:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcmp( mon_tableau, {0x1, 0x2, 0x3});
    Car le compilateur a besoin de stocker le tableau que tu compares quelque part de toute facon....

    Après, sérieusement, si tu en es à 3 octets près dans ta mémoire, tu peux peut être tester plus simplement comme ceci (sous réserve que ton remplissage de tableau suive un ordre logique):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int OK = 0;
    for(int i=0; i<3; i++)
    {
        if(mon_tableau[i] != i)
            break;
    }
    if(i==3)
       OK = 1;
    Mais même là, je pense que les 3 octets que tu économises en données tu les perds dans la taille du code à ajouter...

    Autre solution si tes tableaux sont grands (>1ko par exemple), calculer un CRC (cherche md5 sur google) du tableau théorique et de ton tableau en pratique, et les comparer.

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    ce que je veux faire c'est juste ne pas utiliser des ressources inutilement
    Le problème, c'est qu'appeler une fonction (que ce soit memcmp ou autre) prend des ressources aussi : empilement des arguments sur la pile, exécution de CALL (qui empile EIP à son tour), empilement d'EBP, modification d'ESP, comparaison de tes 3 octets, dépilement d'EBP, modification d'ESP, saut à l'adresse EIP (qui est dépilée). En fait, cela fait beaucoup de cycles CPU gaspillés rien que pour accéder à la fonction et la quitter. Le code qui t'intéresse est en fait seulement ce que j'ai mis en italique. Tout le reste, c'est du gâchis de CPU.

    Si l'optimisation est capitale, évite d'appeler une fonction de comparaison (qui va de toute façon bouffer des ressources). Il est préférable dans ce cas de comparer soi-même les octets nécessaires, et d'intégrer ça en lieu et place de l'appel à memcmp (ou autre), soit à l'aide d'une boucle, soit en testant carrément les octets un par un (s'il y en a que 3, ça va encore).

  9. #9
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Sinon, tu peux toujours faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcmp ( MyTab, "0x010x020x03", 3 )
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcmp ( MyTab, "\x01\x02\x03", 3 )
    Euh, les deux écritures ne sont pas équivalente.

    La première est une chaîne de longueur 12 ('0', 'x', '0', etc.) alors que la seconde est une chaîne de longueur 3.

    Citation Envoyé par jeroman Voir le message
    Si l'optimisation est capitale, évite d'appeler une fonction de comparaison (qui va de toute façon bouffer des ressources). Il est préférable dans ce cas de comparer soi-même les octets nécessaires, et d'intégrer ça en lieu et place de l'appel à memcmp (ou autre), soit à l'aide d'une boucle, soit en testant carrément les octets un par un (s'il y en a que 3, ça va encore).
    Plus sérieusement, il n'est absolument pas certain que l'appel de memcmp() soit systématiquement plus "gourmand" que la comparaison "à la main".

  10. #10
    Membre confirmé Avatar de Gui13
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Par défaut
    Juste pour information, c'est quoi le système embarqué que tu utilises?

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 849
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 849
    Par défaut
    un PIC 8 bits (128Ko de ROM et 3.7Ko de RAM). Pourquoi ?
    merci pour vos réponse => donc la réponse est : il n'y a pas de raccourcis syntaxique pour faire ce que je veux.

  12. #12
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par gl Voir le message
    Euh, les deux écritures ne sont pas équivalente.

    La première est une chaîne de longueur 12 ('0', 'x', '0', etc.) alors que la seconde est une chaîne de longueur 3.
    merci, je me doutais bien de quelque chose comme ça..

    Comme je ne manipule jamais d'hexa, et ue donc je ne connais pas leur notation/usage, je me suis foruvoyé..

    Merci de la correction

  13. #13
    Membre confirmé Avatar de Gui13
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    un PIC 8 bits (128Ko de ROM et 3.7Ko de RAM). Pourquoi ?
    Parce que ca me semblait bien "ultime" comme optimisation. Quand tu dois même optimiser un appel de fonction pour le remplacer par une boucle pour éviter un stack overflow, c'est que le truc sur lequel tu tournes doit être particulièrement limité...

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 849
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 849
    Par défaut
    le gros problème avec ce type de micro c'est qu'en plus d'avoir une mémoire limitée, elle est paginée => des fois pour quelques octets, j'ai du tout re-coder une partie de mes fonctions : c'est pourquoi j'essaie d'éviter au maximum le gaspillage inutile de ressources (tant que ça ne cause pas préjudice à la lisibilité/protabilité du code).

    PS : en fait je crois que c'est mieux d'utiliser strcmp car il y a un paramètre en moins à passer => donc l'octet de gagné pour le caractère '\0' est remplacé par la taille de la chaine

  15. #15
    Membre éprouvé Avatar de sardik
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    135
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2009
    Messages : 135
    Par défaut
    Si tu es vraiment limité pourquoi utilise tu des fonctions des libraires standards... Quand je suis limité en ressources je re code toutes ces petites fonctions pour les tailler à mes besoins et virés les protections inutiles.

    Ensuite 120KO c'est plutôt pas mal comme taille mémoire pour avoir à se soucier d'un seul octet...
    Si tu utilise le compilo C18, Es tu sûr que tu utilise bien le "large data code model" pour la compile de ton code ? (pointeurs codées sur 24bits et non 16) Car sinon tu ne peux pas utiliser les 120KO mais que 64KO (voir moins) d'où tes problèmes d'espace.

  16. #16
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par sardik Voir le message
    Si tu es vraiment limité pourquoi utilise tu des fonctions des libraires standards... Quand je suis limité en ressources je re code toutes ces petites fonctions pour les tailler à mes besoins et virés les protections inutiles.
    Même si parfois c'est effectivement la meilleure chose à faire pour résoudre le problème, ce n'est pas forcément une bonne idée de le faire de manière systématique. En effet certaines de ces fonctions sont suffisamment optimisées pour qu'elles soient plus intéressante, malgré le surcoût de l'appel de fonction et des deux-trois tests supplémentaires, que la version "naïve" que tu vas codé à priori.

    De même que pour la recherche de performance, il est largement préférable de mesurer avant et après et de vérifier si effectivement il y a un gain réel, parfois les résultats sont "surprenants".

  17. #17
    Membre éprouvé Avatar de sardik
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    135
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2009
    Messages : 135
    Par défaut
    Le problème est aussi qu'il est souvent dur à maitriser l'étendue des bibliothèques drainées lors du link... ce qui donne parfois des utilisations mémoires "surprenantes"

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 06/11/2007, 12h36
  2. éliminer un caractere d'un string
    Par no-vice dans le forum Langage
    Réponses: 5
    Dernier message: 09/08/2002, 14h55
  3. Réponses: 3
    Dernier message: 12/06/2002, 21h15
  4. Réponses: 2
    Dernier message: 29/05/2002, 20h43
  5. Probleme sur les chaines de caractere
    Par scorpiwolf dans le forum C
    Réponses: 8
    Dernier message: 06/05/2002, 19h01

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