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 :

hex to int [Débutant(e)]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut hex to int
    Salut les programmateurs C,
    Je suis un débutant (pas complètement je connais python un peu), je poste car je désire prendre contacte avec la communauté C de ce site de forums génial et parce-que j'en ai marre depuis environ une semaine de me trouver seule livré contre mon ordinateur.
    J'apprends le C89 et j'essaie d'écrire un programme ou l'on entre un octet sous notation majuscule hexadécimale et qui est censer renvoyer la valeur en entier convertie.
    et je ne comprend pas pourquoi celui-çi ne marche pas ou presque pas (sûrement du aux conversions de types):
    un caractère hexadécimal est correctement convertie en int mais pas deux et pas les chiffres, car le programme n'entre pas dans la structure conditionnelle destiner a traiter ceux-ci.

    Voici le code barbare de mon déboirs:
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    #include <stdio.h>
    #include <string.h>
    enum {A=10,B,C,D,E,F}	/*contantes d'égalité de caractères hexdécimal a valeurs digitale */ 
    main() {
      char entry[2] ;
      int i =0 ;
      int res=0 ;
      gets(entry) ; /* Entrez un charactère [A-B] sa fonctionne mais pas deux nie les chiffres */
     
      while ( i < strlen(entry) ) {
        if (i == 0) {
     
          if (( (int) entry[i]) >= 10) { 
    	if (((int) entry[i]) == 'A') {
    	  res=A ;
    	  }
    	else if (((int) entry[i]) == 'B') {
    	  res=B ;
    	  }
    	else if (((int) entry[i]) == 'C') {
    	  res=C ;
    	  }
    	else if (((int) entry[i]) == 'D') {
    	  res=D ;
    	  }
    	else if (((int) entry[i]) == 'E') {
    	  res=E ;
    	  }
    	else if (((int) entry[i]) == 'F') {
    	  res=F ;
    	  }
    	}
          else {
    	printf("never go in this block\n") ; /* le programme n'entre jamais dans ce block */
    	res=(int) entry[i] ;
     
     
        }
        res= res * 16	;
        }
     
        else {
          if ( ((int) entry[i]) >= 10) { 
    	if (((int) entry[i]) == 'A') {
    	  res=A ;
    	  }
    	else if (((int) entry[i]) == 'B') {
    	  res=B ;
    	  }
    	else if (((int) entry[i]) == 'C') {
    	  res=C ;
    	  }
    	else if (((int) entry[i]) == 'D') {
    	  res=D ;
    	  }
    	else if (((int) entry[i]) == 'E') {
    	  res=E ;
    	  }
    	else if (((int) entry[i]) == 'F') {
    	  res=F ;
    	  }
    	}
          else {
    	res=(int) entry[i] ; /* le programme n'entre jamais dans ce block */
    	}
          res=res+res ;
        }
        i++ ;
     
      }
      printf("%d\n",res) ;
    }
    PS: je poste pour apprendre et pas résoudre le problème: pas la peine de faxer la réponse, des bons conseils serai la bienvenue:
    le mieux serai que chacun fournisse une réponse didactiellement commenter a sa façon (sa version).
    Et si vous pourriez écrire une fonction de traitement au lieu des structures conditionnel ca serai sympa car je n'y arrive pas: j'aimerai apprendre.

    Merci pour vos réponses éclairé.

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Salut ! J'aime bien la démarche de compréhension ^^

    Tu apprends peut-être le C avec le K&R, mais il y a justement une chose qu'ils ne "font pas bien" dans ce livre : la façon d'écrire le prototype de la fonction main. On devrait écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int main(void)
    // ou
    int main(argc int, argv *char[])
    Il existe des fonctions toutes faites en C pour faire ça, on va les exclure pour le moment car je pense que ce n'est pas ce que tu souhaites ^^

    Après ces remarques, attaquons le code. Déjà, chez moi, avec gcc, il ne compile pas. J'ai des erreurs et aussi des warnings. L'erreur vient de l'absence de ; à la fin de la ligne avec l'enum. De plus, si tu ne nommes pas ton enum, tu ne pourras pas y accéder par la suite, me semble t-il.

    Citation Envoyé par Bktero
    /!\ Il ne faut jamais utiliser la fonction gets /!\
    http://man.developpez.com/man3/gets.3.php --> voir la section BOGUE
    http://c.developpez.com/faq/index.ph..._gets_vs_fgets --> il faut utiliser fgets() en remplacement
    Un code exemple : il suffit de taper "bonjour" pour voir que ça va être le bazar.
    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
    int main(int argc, char *argv[])
    {
        struct
        {
            char chaine[4] ;
            int entier;
        } demo ;
     
        demo.chaine[0] = 'a';
        demo.chaine[1] = 'b';
        demo.chaine[2] = 'c';
        demo.chaine[3] = '\0';
        demo.entier = 42;
     
        printf("'%s' %d\n", demo.chaine, demo.entier);
     
        printf("Saisir une chaine : \n");
        gets(demo.chaine);
     
        printf("'%s' %d\n", demo.chaine, demo.entier);
     
        return demo.entier;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( i < strlen(entry) )
    Détail : la fonction est évaluée à chaque itération. D'un point de vue performance, cela peut-être embêtant. Si un jour tu as des problèmes de vitesse, sache que tu peux créer une variable contenant le retour de strlen() et comparer i à cette variable.

    En C, tout est entier. Les types int, char, short, long, size_t, intprt_t, ptrdiff_t, j'en passe et des wagons sont tous des entiers binaires.
    Ici, tu testes donc si la valeur contenue dans un char est supérieure à 10. Si tu connais ta table ASCII des caractères, tu sais qu'autant caractère alphanumérique ne répond à ça. Tu devrais donc comprendre pourquoi ça ne marche pas ^^

    Ensuite, je pense que ta boucle est très compliquée... Les entrelacements de if /else if / if m'ont l'air hasardeuses. Comme en Python, un code bien indenté est primordiale pour la compréhension. Bref, revois un peu ton algo

    Perso, l'algo bête qui me vient à l'idée en premier est de parcourir la chaine de caractères et de faire un switch / case sur chaque caractère. Il y a sûrement des méthodes plus efficaces mais elle est simple pour un débutant.

  3. #3
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 083
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 083
    Par défaut
    Sinon strtol fait cela très facilement

  4. #4
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Merci pour vos réponses:
    j'apprends le C89 donc il faut le préciser (c'est grave l'ancienneté de la version ?)
    /* (C89) ? (! classe) : C99 ; */
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -fgnu89-inline code.c
    mais ce n'est pas indispensable.
    A vrai dire je débute vraiment j'en suis au chapitre 3 de K/R.
    -Je ne comprend pas le mot clef struct de ton code et la notation pointé qui en suit me fait penser que j'ai affaire a un objet ou du moins a une structure.
    -Le nommage d'enum tu me l'apprend.
    -La base sont les int mais j'ai quand même beaucoup de mal avec les types.

    Mais j'ai solutionner mon problème avec le code suivant que j'aimerai améliorer afin de aussi pouvoir afficher la valeur entrer d'oû les commentaires préfixer "for futur:":
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    #include <stdio.h>
    #include <string.h>
    enum {HEX_A=10,HEX_B,HEX_C,HEX_D,HEX_E,HEX_F} ;
    enum {HEX_0=0,HEX_1,HEX_2,HEX_3,HEX_4,HEX_5,HEX_6,HEX_7,HEX_8,HEX_9} ;
    main() {
      char entry[4] ;
      int i = 0 ; /* index of  hex data */
      int res_1, res_2, res ; /* result containers */
      int ctrl=0 ; /* control var for special case '0Xh' entry */
      int hex ; /* for futur:  to store the hex entry value */
      res_1 = res_2 = 0 ;
     
      gets(entry) ;
      if (((strlen(entry)) ==4 ) && ((entry[0] == '0') && entry[1] == 'x' || entry[1] == 'X') && ((get_hex(entry[2]) != 16 ) && (get_hex(entry[3]) != 16) )) {
        i=2 ; /* set index over '0x' */
        /* for futur:           hex=entry[2]+entry[3] ; set the hex entry value */
      }
      else if (((strlen(entry)) == 3 ) && ((entry[0] == '0') && entry[1] == 'x' || entry[1] == 'X') &&  (get_hex(entry[2]) != 16 )) {
        i=2 ;  /* set index over '0x' */
        ctrl=1 ;  /* set the control variable for the case 'Oxh' value */
        /* for futur:          hex=entry[3] ; set the hex entry value */
      }
      else if (((strlen(entry)) <= 2) && ( (get_hex(entry[0]) != 16 ) && (get_hex(entry[1]) != 16) )) {
        i=0 ;  /* set index without '0x' */
        /* for futur:           hex=entry[0]+entry[1] ; set the hex entry value */
      }
      else {
        printf("Enter an hex octet value please !!!\n") ;
        return ;
      }
      if (! ctrl) {   
      res_1=get_hex(entry[i]) ;  /* i=2 case '0xhh' or i=0 case 'hh' */
      i += 1 ;
      res_2=get_hex(entry[i]) ;  /* i=2 case '0xhh' or i=0 case 'hh' */
      res=(res_1 * 16) + res_2 ; 
      }
      else {
        res=get_hex(entry[i]) ; /* i=2 case '0xh' */
      }
      /*for futur:  printf("hex: %c = %i\n",hex,res) ; printf with the entry value */
      printf("%i\n",res) ;
    }
     
    get_hex(int c) {
      char res ;
      res=(char) c ;
      if ((res == 'F') || (res == 'f')) {
        return HEX_F ;
      }
      else if ((res == 'E') || (res == 'e')){
        return HEX_E ;
      }
      else if ((res == 'D') || (res == 'd')) {
        return HEX_D ;
      }
      else if ((res == 'C') || (res == 'c')) {
        return HEX_C ;
      }
      else if ((res == 'B') || (res == 'b')) {
        return HEX_B ;
      }
      else if ((res == 'A') || (res == 'a')) {
        return HEX_A ;
      }
      else if (res == '9') {
        return HEX_9 ;
      }
      else if (res == '8') {
        return HEX_8 ;
      }
      else if (res == '7') {
        return HEX_7 ;
      }
      else if (res == '6') {
        return HEX_6 ;
      }
      else if (res == '5') {
        return HEX_5 ;
      }
      else if (res == '4') {
        return HEX_4 ;
      }
      else if (res == '3') {
        return HEX_3 ;
      }
      else if (res == '2') {
        return HEX_2 ;
      }
      else if (res == '1') {
        return HEX_1 ;
      }
      else if (res == '0') {
        return HEX_0 ;
      }
      return 16 ;
     
    }
    Désolé pour les structures conditionnelles complexe: j'ai fait comme j'ai pu.

    Je suis ouvert a tous commentaires et conseils merci d'avance pourquoi je vous signifie ma gratitude pour ce qui a déjà été dit.

  5. #5
    Membre très actif

    Femme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    593
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 593
    Par défaut
    Salut,


    Personnellement je te conseille d'apprendre le C99 (déjà vieux 14 ans...).
    Le minimum pour faire une code propre et d'utilisation les options de compilation suivante : gcc -std=c99 -Wall -Werror

    Si tu veux pousser le vice : gcc -std=c99 -Wall -Werror -Wextra
    Et si tu te sent d'humeur pédante : gcc -std=c99 -Wall -Werror -Wextra -pedantic

    L'option -O2 va optimiser le code généré mais également lever des warnings supplémentaires.

    Si tu veux débuger le code avec gdb rajoute les options -O0 -g

    @+

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 083
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 083
    Par défaut
    Sinon strtol, non ça le fait pas?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(void)
    {
        const char *ch = "4D5";
        long n = strtol(ch, NULL, 16);
        printf("%d\n", (int)n); /* Affiche 1237 */
        return 0;
    }

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    J'ai chercher la documentation de la library standart sur le net et je suis tomber sur le wiki et je n'ai pas trouver de document au format *.pdf ou *.html a télécharger officiel descriptif de la library standart du C ANSI mais j'ai juste les annexes du livre de K&R et le wiki (pas chercher assez longtemps car je n'ai pas trouver de site officiel du C) ?
    N'existe t il pas a l'image de python un site officiel ("site officiel du C ANSI" dans google fait choux blanc !) ou l'on peut trouver de la doc. car essayer de comprendre les fichiers sources en tant que débutant n'est pas facile et mêne à des erreurs comme:
    Ca n'existe pas. C est une norme que chaque compilateur implémente. Il faut donc regarder les documentations des compilateurs les man pages de ton OS. Néanmoins, comme un compilateur digne de lui-même respecte la norme, tu retrouves presque toujours la même chose. Tu peux donc de servir des pages de manuel de Developpez comme référence : http://man.developpez.com/ Elles sont faites pour Linux, mais je m'en sers aussi pour Windows. Tu auras en revanche des choses non disponibles sous Windows (et réciproquement) et il faudra alors chercher sur le site de Microsoft (msdn).


    La solution que je voit mais qui ne me plais pas est de copier le fichier stdlib.h puis de modifier la valeur de RAND_MAX et de l'inclure comme ca:
    Solution à bannir strictement !!! Regarde le lien que je te donne dans mon précédent message, c'est la page de manuel de rand() et elle t'explique comment faire (faut lire un peu ce que j'écris ^^)


    Je ne connait pas la table ASCII par cœur (quel honte !!!) mais je m'en m'excuse car python fournis une primitive chr(int) qui renvoie le caractères correspondant a l'argument donnée.
    Pratique ! Tu vois maintenant que 5 n'est pas un caractère affichable et que 10 est un \n donc putchar(10) affiche un retour à la ligne (donc "presque rien").


    Je comprend que 'i' désigne le code ASCII (ANSI ?) et que "i" désigne le caractère i
    'i' est le caractère i et a une valeur numérique (donnée par la table ASCII). "i" est une chaine de caractère en C !

    mais avec les retours de fonctions ( gets(char s[]), getchar() ) ça s'embrouille un peu dans mon esprit.
    getchar() renvoie un caractère ou EOF. Obsidian a très bien expliqué pourquoi le type de retour est donc int et no char.


    Merci pour le conseil mais fgets a un squelette trop complexe pour l'instant (je ne l'ai pas essayer mais je vais le faire) d'après l'annexe du livre de K&R.
    Ce n'est pourtant pas négociable !

    Merci beaucoup pour vos réponses: j'ai bien été reçu dans la communauté C du site de forums de programmation francophone le plus génial qu'il soit.

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    J'ai chercher la documentation de la library standart sur le net et je suis tomber sur le wiki et je n'ai pas trouver de document au format *.pdf ou *.html a télécharger officiel descriptif de la library standart du C ANSI mais j'ai juste les annexes du livre de K&R et le wiki (pas chercher assez longtemps car je n'ai pas trouver de site officiel du C) ?
    Consultez la norme C99

    Tu trouveras la description de la bibliothèque standard dans le chapitre 7

  9. #9
    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
    Plus d'infos à propos de RAND_MAX: Ce n'est pas modifiable. rand() retourne systématiquement une valeur compris entre 0 et le RAND_MAX du compilo, et c'est à toi qu'il appartient ensuite de la faire rentrer dans le moule que tu veux.
    • La façon paresseuse, c'est un bète modulo: Pour une valeur entre 1 et 6, on fait rand() % 6 + 1. Malheureusement, ça peut exposer des faiblesses du générateur, surtout si le nombre de valeurs voulues est une puissance de deux (j'en ai fait l'expérience).
    • La façon plus utilisée, c'est un ajustement proportonnel avec des nombres à virgule flottante: rand() / (double)RAND_MAX ramènera le résultat à l'intervalle [0.0 ; 1.0] (diviser par RAND_MAX+1.0 donnera l'intervalle [0.0 ; 1.0[ à la place), qu'une multiplication étendra ensuite.

    Voir aussi l'entrée de la FAQ C sur les nombres aléatoires.
    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.

  10. #10
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    oh, et pour la table ascii, il y a la classique "man ascii", qui est dans nos pages man

Discussions similaires

  1. Conversion d'un String hex en int ne fonctionne pas
    Par Shirase_Akira dans le forum Langage
    Réponses: 7
    Dernier message: 14/08/2012, 17h49
  2. [.COM] Réserver de la RAM fct 48h int 21h
    Par bulerias dans le forum x86 16-bits
    Réponses: 5
    Dernier message: 06/12/2010, 14h33
  3. Int to Hex et 0xData
    Par LiaGalanodel dans le forum Langage
    Réponses: 5
    Dernier message: 20/11/2010, 11h29
  4. [Dev c++ 4] implicite declaration of function "int kbhi
    Par Torpedox dans le forum Dev-C++
    Réponses: 5
    Dernier message: 01/01/2003, 13h37
  5. [VB6]fonction inverse de Hex (nombres hexadécimaux)
    Par Guigui_ dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 08/10/2002, 19h31

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