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 :

Conversion Hexa vers chaine de caractères


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut Conversion Hexa vers chaine de caractères
    Bonjour à la communauté,

    J'ai ci-dessous une fonction que me sert à convertir une chaine hexadécimale (stringName) en chaine de caractère (o_cData).

    0x00115660AEFF ===> "00115660AEFF"

    Les caractères de la chaine héxa sont appelé deux à deux avant de remplir la nouvelle chaine avec un sscanf, et c'est la que ça coince.
    Peut-être qu'un sprintf serait plus approprié ?
    Pourriez-vous m'aider sur ce point ?

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    int fonction() {
      char *stringName = "0x00115660AEFF";  //Chaine de caractère d'entrée
      unsigned int nbDataSimuFile = 15; //Nombre de caractère de la chaine en comptant le caractère de fin
      int o_iNbDatas;  //Nombre de caractère de la chaine de sortie
      unsigned char *o_cData; //Chaine de caractère de sortie
     
     
      int j = 0;  //Permet de sélectionner l'emplacement dans la chaine de caractère de sortie
     
      o_cData = malloc (sizeof(char) * nbDataSimuFile - 2));  //Permet d'allouer de la mémoire à la chaine de sortie sans les deux premiers caractères
     
      if('0' == stringName[0] && 'x' == stringName[1]) { //Vérification que la chaine d'entrée soit bien en hexadécimale
        *o_iNbDatas = (nbDataSimuFile - 3) / 2;  //Calcul du nombre de caractère de sortie
        o_cData = malloc (sizeof(char) * (*o_NbDatas));  //Nouvelle allocation mémoire pour la chaine de sortie
     
        for (int i; i < nbDataSimuFile - 1; i += 2) {  //Boucle for pour cibler 2 termes par termes
          char temp[3];
          temp[0] = stringName[i];  //Décomposition de l'information
          temp[1] = stringName[i + 1];
          temp[2] = '\0';
     
          sscanf((char*) o_cData[j], "%c%c", temp); //Remplissage de la chaine de sortie
     
          j += 2;
     
        }
     
        return 1;
     
      } else {
     
        return 0;
     
      }
    }
    Cordialement
    Bastien

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    C'est vraiment le code ?
    Que vaut i au début dans for (int i; i < nbDataSimuFile - 1; i += 2) ?
    Sinon y'a sûrement plus simple avec juste des strncpy et memcpy.
    Ou encore parce que ta chaîne de sortie est juste la chaîne d'entrée privée des 2 premiers caractères. Donc c'est juste un décallage de la chaîne d'entrée. out = input + 2; et aucune copie n'est nécessaire.
    Si tu veux absolument une copie, strncpy ou memcpy. Et aucunement besoin de boucle.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Oui, pardon, j'ai fait une erreur en recopiant, c'est int i = 2 dans la boucle for.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Ok mais cette boucle n'a de toutes façons rien à faire.
    Tout ce dont tu as besoin c'est memcpy(o_cData, stringName + 2, nbDataSimuFile - 2);
    Btw, vu que ton o_cData est interne et fait une allocation, ta fonction est juste un puit à fuite mémoire telle quelle.
    Pourrait-on voir la vraie fonction ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Nous ne pouvons pas décaler de deux car la chaine de caractère doit être en hexa.
    Je m’explique :
    Si la chaine d’entrée est 0x4147 soit un char [6]
    La chaine de sortie doit être 4147 soit un char[4]
    Pour que s’il l’on fasse un printf ou un sprintf de la chaine de sortie, on obtient AG.

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    int fonction(int i_portNumber, int *o_iNbDatas, unsigned char *o_cData) {
      int functionReturn = 0;
      char *stringName = 0;  //Chaine de caractère d'entrée
      unsigned int nbDataSimuFile = 0; //Nombre de caractère de la chaine en comptant le caractère de fin
      int o_iNbDatas;  //Nombre de caractère de la chaine de sortie
      int status = STATUS_NO_ERREUR;
      char tmpString[MAX_LONG_MSG_SIZE];  //Chaine caractère temporaire
     
     
      int j = 0;  //Permet de sélectionner l'emplacement dans la chaine de caractère de sortie
     
      //On récupère la donnée d'un fichier
      sprintf(StrTexte, "%s%d", (char*)__func__, i_portNumber);  //StrText est globale : char strTexte[LONG_MAX_MSG_SIZE] = "";
      functionReturn = SIMU_GenerateString((char*)PLG_SIMU_NAME, StrTexte, &nbDataSimuFile, &stringName);  //PLG_SIMU_NAME est globale : const char PLG_SIMU_NAME = "PLG";
     
      if (0 == functionReturn && 0 != nbDataSimuFile)
      {
        o_cData = malloc (sizeof(char) * nbDataSimuFile - 2));  //Permet d'allouer de la mémoire à la chaine de sortie sans les deux premiers caractères
     
        if('0' == stringName[0] && 'x' == stringName[1]) { //Vérification que la chaine d'entrée soit bien en hexadécimale
     
          status = STATUS_NO_ERROR;
          *o_iNbDatas = (nbDataSimuFile - 3) / 2;  //Calcul du nombre de caractère de sortie
          o_cData = malloc (sizeof(char) * (*o_NbDatas));  //Nouvelle allocation mémoire pour la chaine de sortie
     
            for (int i; i < nbDataSimuFile - 1; i += 2) {  //Boucle for pour cibler 2 termes par termes
            char temp[3];
            temp[0] = stringName[i];  //Décomposition de l'information
            temp[1] = stringName[i + 1];
            temp[2] = '\0';
     
            sscanf((char*) o_cData[j], "%c%c", temp); //Remplissage de la chaine de sortie
     
            j += 2;
     
          } else {
     
          status = STATUS_ERREUR;
     
      } else {
     
        status = STATUS_NO_ERREUR;
     
      }
     
      return status;
     
    }
    Cordialement

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Donc to objectif n'est pas de convertir 0xYYZZ en "YYZZ" comme tu l'annonces dans ton premier post, mais de convertir "0xYYZZ" en une chaîne qui s'échapperait en "\xYY\xZZ" ? De sorte que "0x414243" donne "ABC"?
    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.

  7. #7
    Invité
    Invité(e)
    Par défaut
    oui, partiellement, en fait la chaine de caractère dans le fichier peut-être 414243 ou 0x414243. Le second cas est considéré comme une erreur, c'est pour cela que nous la convertissons en hexa, pour que dans le cas où nous lisons une des deux chaines, nous obtenions ABC.
    Mais la chaine en entrée n'a que les caractère : 0123456789ABCDEF.

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Dans ce cas, c'est plutôt facile:
    Code C : 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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    int ParseHex(char c)
    {
    	if(c >= '0' && c <= '9')
    		return c-'0';
    	switch(c) /*Avec un switch c'est valide pour tous les encodages permis par la norme C*/
    	{
    	case 'A': case 'a': return 10;
    	case 'B': case 'b': return 11;
    	case 'C': case 'c': return 12;
    	case 'D': case 'd': return 13;
    	case 'E': case 'e': return 14;
    	case 'F': case 'f': return 15;
    	}
    	return 0;
    }
     
    char* HexToString(char const *inputString)
    {
    	size_t length;
    	char *ret;
    	/* Si ça commence par 0x, on le saute */
    	if(strncmp(inputString, "0x", 2)==0 || strncmp(inputString, "0X", 2)==0)
    		inputString += 2;
     
    	length = strlen(inputString)/2;
    	ret = malloc(length * sizeof *ret);
    	if(ret != NULL)
    	{
    		size_t i;
    		for(i=0 ; i<length ; i++)
    		{
    			char highNibble =  inputString[i*2];
    			char lowNibble = inputString[i*2+1];
    			int value = ParseHex(highNibble) << 4 | ParseHex(lowNibble);
    			ret[i] = (char)value;
    		}
    	}
    	return ret;
    }
    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.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Cette réponse me parait extrêmement limpide et je vous en remercie.
    Par contre, j'ai un soucie avec la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char highNibble =  inputString[i*2];
    Où inputString[0] vaut 4 mais char highNibble me sort la valeur décimale 52.

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    inputString[0] ne vaut pas 4, il vaut '4', qui en encodage ASCII (et tous les encodages qui en sont dérivés) est égal à 52.
    Par contre, normalement ParseHex('4') retournera 4.
    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.

  11. #11
    Invité
    Invité(e)
    Par défaut
    C'est bon, cela fonctionne à merveille, j'avais fait une petite erreur dans mon code ^^

    Merci
    Cordialement
    Bastien

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

Discussions similaires

  1. Conversion guint vers chaine de caractères
    Par diophantes dans le forum GTK+ avec C & C++
    Réponses: 15
    Dernier message: 25/04/2007, 18h30
  2. conversion entier vers chaine de caratères
    Par naima2005 dans le forum C++
    Réponses: 3
    Dernier message: 20/08/2006, 02h14
  3. [Système] Conversion d'une chaine de caractère en hexa
    Par Florent08800 dans le forum Langage
    Réponses: 5
    Dernier message: 10/07/2006, 15h32
  4. conversion d'une chaine de caractère en int
    Par greg13 dans le forum C++
    Réponses: 3
    Dernier message: 25/08/2005, 16h18

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