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

  1. #1
    Membre expérimenté
    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
    Points : 1 742
    Points
    1 742
    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é.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    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 éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    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 : 3 817
    Points : 7 110
    Points
    7 110
    Par défaut
    Sinon strtol fait cela très facilement
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  4. #4
    Membre expérimenté
    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
    Points : 1 742
    Points
    1 742
    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.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  5. #5
    Membre expérimenté

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

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 429
    Points
    1 429
    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 éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    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 : 3 817
    Points : 7 110
    Points
    7 110
    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;
    }
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    @Fred : comme je l'ai dit, le but du jeu pour lui est sûrement de recoder une fonction équivalente à strtol() justement ^^

    @mith06 :
    L'option -O2 va optimiser le code généré mais également lever des warnings supplémentaires.
    Je ne savais pas que ça pouvait générer des warnings supplémentaires. Que peut-il se passer ? À quoi faut-il faire attention ?

    @Luke spywoker :
    Tes options de compilation ne sont pas bonnes. Ton option a à voir avec les fonctions inline, je sais pas comment tu l'as trouvée d'ailleurs XD
    Pour compiler, sers toi de gcc -Wall -Wextra
    Tu peux t'amuser à mettre -Werror (ce n'est pas bête d'ailleurs, quoi que cela ne permet pas de différencier erreurs et warnings du coup).
    Il faut utiliser -ansi ou -std=c99 pour choisir le standard de la norme.

    Pour ce qui est du code..... Tu penses pas pouvoir faire plus simple ? :s

  8. #8
    Membre expérimenté
    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
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour vos réponses,
    Pour ce qui est du code..... Tu penses pas pouvoir faire plus simple ? :s
    Les structures de contrôles, pas si compliquer que ça, filtre l'entrer afin que ca soit bien un nombre hexadécimal en appelant en partie la fonction get_hex ca fait des appels | utilités supplémentaires de la fonction et fixe l'index en fonction de la notation avec | sans '0x'.

    Mais j'ai un nouveau problème: je ne comprend pas pourquoi je ne peut copier un tableau a l'envers:
    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
    #include <stdio.h>
    #include <string.h>
     
    char entry[255] ; /* déclaré en extern */
    char entry_reverse[255] ; /* déclaré en extern */
     
    main() {
     
      gets(entry) ;
      reverse() ;
      printf("%s\n", entry_reverse) ; /* ici ca ne marche pas */
    }
     
    reverse(void){
      int i,j ;
      i=0 ;
      j=strlen(entry) ;
      while (i <= 0) {
        entry_reverse[i]=entry[j] ; /* ici ca ne marche pas */
        i++ ;
        j-- ;
      }
    }
    `
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  9. #9
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Quelques recommandations :

    1- Tu dois spécifier dans la déclaration le type de retour des fonctions. Utiliser un type par defaut (int) est maintenant obsolète
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int main(void) {...}
    void reverse(void){...} //puisque reverse ne renvoie rien
    2- gets() est obsolète : utiliser à la place fgets() sur le flux stdin. Attention à ce que fgets(), au contraire de gets(), met le '\n' terminant la ligne tapée au clavier dans le tampon.

    3- Sur le problème proprement dit, la fonction reverse() :
    - la boucle ne marche pas : le test dit while (i <= 0)avec i initialisé à 0 puis incrémenté dans la boucle. On a toujours i>=0. La boucle sera effectuée une fois au début pour i==0 puis i passe à 1, le test devient faux et la boucle s'arrête
    - le test devrait porter sur la valeur de j, pas de i while(j>=0). .
    - une chaine de caractère doit comporter un '\0' terminal. Lorsque la chaine d'origine a été recopiée dans la chaine de destination, il faut ajouter dans cette dernière ce caractère terminal
    - strlen() ne compte pas le '\0' terminal. Par exemple si on a la chaine "1234", strlen() renvoie 4 bien que la chaine fasse 5 bytes. Le dernier élément de la chaine (le '4') est à l'indice 3 soit strlen()-1. Celui à l'indice strlen() est le '\0' terminal. L'initialisation de j est donc fausse : si on copie cet élement en position 0 de la chaine de destination, celle-ci sera considérée, en tant que chaine, comme vide.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pour parcourir entièrement une chaîne, le plus simple est de profiter du fait qu'en C une chaîne se termine systématiquement par le caractère nul '\0'.
    Ainsi tu peux faire:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(i=0 ; chaine[i]!='\0' ; ++i)
    {
    	/*Ton code ici*/
    }
    Une autre garantie du C est que les chiffres de '0' à '9' se suivent forcément, et dans cet ordre. Il n'y a pas de garantie similaire pour les lettres: les lettres A-F et a-f se suivent en ASCII et en EBCDIC, mais le standard n'interdit pas d'utiliser un jeu de caractères différent.
    Ainsi tu peux faire:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    char c = chaine[i];
    int valeurCarac = 0;
    if(c >= '0' && c<= '9')
    {
    	valeurCarac = c - '0';
    }
    /*Note: Remplacer ça par un switch() quand tu auras appris ce que c'est*/
    else if(c=='a' || c=='A') { valeurCarac = 10; }
    else if(c=='b' || c=='B') { valeurCarac = 11; }
    else if(c=='c' || c=='C') { valeurCarac = 12; }
    else if(c=='d' || c=='D') { valeurCarac = 13; }
    else if(c=='e' || c=='E') { valeurCarac = 14; }
    else if(c=='f' || c=='F') { valeurCarac = 15; }
    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
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Dans ce cas là, autant écrire directement:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    char c = toupper(chaine[i]);
    int valeurCarac = 0;
    if(c >= '0' && c<= '9')
    {
    	valeurCarac = c - '0';
    }
    else if (c >= 'A' && c <= 'F')
    {
    	valeurCarac = c - 'A' + 10;
    }

    L'appel à toupper permet de gérer simplement les lettres hexadécimales, en passant tout en majuscule avant les comparaisons. Du coup, ça simplifie les comparaisons. Ça passera sans soucis en ASCII ou en UTF-8.
    Documentation officielle GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels par l'exemple (platform-demos):
    GTK (tous langages)

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ça passe en ASCII, tous les ASCII étendus et EBCDIC, mais ça n'est pas garanti par le standard C et Luke le wokeur d'espions a précisé spécifiquement qu'il apprenait le C standard C89.
    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.

  13. #13
    Membre expérimenté
    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
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour vos nombreuses réponses,
    J'ai terminer le chapitre 4 de K&R ANSI, et je galère venant du python (qui est beaucoup plus flexible).
    J'ai améliorer le programme de conversion de valeurs hexadécimal en C qui prend maintenant en entré un chiffre hexadécimal qui ne soit pas limité a un octet.

    Par ailleurs j'ai réussi aussi a copier une chaine (tableau de caractères) avec '\0' à la fin mais j'arrive pas a l'afficher avce printf().

    Mais j'ai beaucoup de difficultés avec mes nouvelles idées de bout de code pour apprendre le langage, notamment pour les entrées gets() et getchar(), je cherche a créer un programme de calcule de solution d'opération de base seulement je n'arrive pas a obtenir une valeur True quand je compare l'entrer avec l'opération soumise:

    Voici un bout de code qui ne fonctionne pas du tout:
    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
    #include <stdio.h>
    #include <stdlib.h>
    #undef RAND_MAX
    #define RAND_MAX 10 
    /*ca ne fonctionne pas de rédéfinir la valeur maximal renvoyer par rand() */
     
    main() {
      int c ;
      int op1, op2 ;
      op1=rand() ;
      op2=rand() ;
      /* pour la démonstration de la suite car rand() ne fonctionne pas  comme décrit (voir plus haut) on va définir op1 et op2 directement */
      op1=2 ;
      op2=3 ;
      printf("%i + %i\n",op1,op2) ;
      while ((c=getchar()) != '\n') {
        ;
      }
      /* comme ca non plus ca ne marche pas:  c=getchar() ; */
      if ((op1+op2) == c ) { /* ne fonctionne pas */
        printf("win\n") ; 
      }
      putchar(c) ; /* vide */
      printf("%i\n",c) ; /* imprime 10 alors que j'ai taper 5  et printf("%d\n",c) pareil ;*/
      /* 
      Et si je me met a galérer avec une entrée avec gets() j'ai des problèmes de conversion de de type qui même
      correctes ne satisfont pas la structure conditionnelle if...
      */
     
    }
    Le problème vient des entrée.

    PS: Je sais car j'ai lu, que beaucoup de gens ont abandonner la voix du C en cours de route débouter par la difficultés: heureusement que j'ai commencer avec python.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  14. #14
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Ah ! La souplesse de Python ^^
    Moi aussi j'ai été perturbé quand je suis passé de C à Python mais le sens inverse : j'aurais aimé qui ne me laisse pas faire ce que je veux.

    http://man.developpez.com/man3/rand.3.php --> il faut appeler srand() avant d'utiliser rand(), ça te permet d'avoir des résultats différents d'une exécution du programme à l'autre.

    Tu ne peux pas modifier RAND_MAX ainsi. Les #define sont définies par unité de compilation. Ici, tu modifies la valeur dans main.c et non dans le fichier où regarde rand() pour faire son calcul. La page de manuel te montre comment obtenir un nombre dans l'intervalle souhaité.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ((c=getchar()) != '\n')
    Donc après cette boucle, c contient \n.

    Connais-tu le caractère donc le code ASCII est 5 ?

    putchar(c) ; /* vide */
    printf("%i\n",c) ; /* imprime 10 alors que j'ai taper 5 et printf("%d\n",c) pareil ;*/
    Vide ou retour à la ligne ? 10 ? Comme la valeur ASCII de LF = \n ? Comme la valeur forcée par ta boucle while ?

    Tu vois où je veux en venir ?

    PS : encore une fois, il ne faut pas utiliser gets() ! Il faut lui préférer fgets().

  15. #15
    Membre expérimenté
    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
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour la réponse,
    La page de manuel te montre comment obtenir un nombre dans l'intervalle souhaité.
    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:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include <stdlib.h>
    #undef RAND_MAX
    #def RAND_MAX 10
    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:
    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.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>>chr(5)
    '\x05'
    >>> chr(10)
    '\n'
    >>>
    Et j'ai un problème de compréhension concernant les caractères:
    Je comprend que 'i' désigne le code ASCII (ANSI ?) et que "i" désigne le caractère i mais avec les retours de fonctions ( gets(char s[]), getchar() ) ça s'embrouille un peu dans mon esprit.

    Par contre j'ai réussi a obtenir une entrée comparable avec scanf() pour mon problème de calcule qui fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* pseudo code */
    /* int i=1 ; */
    /*dans une boucle
    op1=srand(i)% (<10)  ;
    op2=srand(i)% (<10) ;
    i++ ;
    */
    car je narrive pas a limiter la valeurs de op1 et de op2 sans modulo.

    PS : encore une fois, il ne faut pas utiliser gets() ! Il faut lui préférer fgets().
    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.

    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.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  16. #16
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    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.

  17. #17
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    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
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    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.

  19. #19
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    oh, et pour la table ascii, il y a la classique "man ascii", qui est dans nos pages man
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

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