Précédent   Forum du club des développeurs et IT Pro > C et C++ > C > Débuter
Débuter Forum d'entraide pour débuter en langage C. Avant de poster -> FAQ C
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 14/01/2013, 20h17   #1
Luke spywoker
Membre éclairé
 
Avatar de Luke spywoker
 
Homme
Etudiant informatique autodidacte
Inscription : juin 2010
Messages : 591
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Etudiant informatique autodidacte

Informations forums :
Inscription : juin 2010
Messages : 591
Points : 370
Points : 370
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 :
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...
Blog: http://3dcyberspace.unblog.fr/
Site: Sanctuaire cybernétique
Luke spywoker est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2013, 21h20   #2
Bktero
Expert Confirmé Sénior
 
Avatar de Bktero
 
Ingénieur systèmes embarqués
Inscription : juin 2009
Messages : 1 717
Détails du profil
Informations personnelles :
Âge : 25
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Ingénieur systèmes embarqués
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2009
Messages : 1 717
Points : 4 217
Points : 4 217
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 :
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 :
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 :
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.
__________________
Si Code::Blocks vous dit undefined reference to 'socket@12', cela signifie que vous avez un problème d'édition des liens. Allez dans Projects / Build Options / Linker Settings / Add et renseigner ici les .a qui vont bien. Exemple pour les sockets : C:\Program Files\CodeBlocks\MinGW\lib\libws2_32.a

Pour les adeptes du langage SMS, allez ici et ramenez la traduction française ^^

Pour vos problèmes d'embarqué, utilisez le forum dédié !
Bktero est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 14/01/2013, 22h23   #3
fred1599
Membre Expert
 
Avatar de fred1599
 
Homme Fred
Enseignant
Inscription : juillet 2006
Messages : 1 324
Détails du profil
Informations personnelles :
Nom : Homme Fred
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : juillet 2006
Messages : 1 324
Points : 1 823
Points : 1 823
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)
fred1599 est déconnecté   Envoyer un message privé Réponse avec citation 02
Vieux 15/01/2013, 06h27   #4
Luke spywoker
Membre éclairé
 
Avatar de Luke spywoker
 
Homme
Etudiant informatique autodidacte
Inscription : juin 2010
Messages : 591
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Etudiant informatique autodidacte

Informations forums :
Inscription : juin 2010
Messages : 591
Points : 370
Points : 370
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 :
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 :
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...
Blog: http://3dcyberspace.unblog.fr/
Site: Sanctuaire cybernétique
Luke spywoker est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2013, 17h11   #5
mith06
Membre confirmé
 
Ingénieur développement matériel électronique
Inscription : juillet 2010
Messages : 142
Détails du profil
Informations professionnelles :
Activité : Ingénieur développement matériel électronique
Secteur : Industrie

Informations forums :
Inscription : juillet 2010
Messages : 142
Points : 203
Points : 203
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

@+
mith06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2013, 17h48   #6
fred1599
Membre Expert
 
Avatar de fred1599
 
Homme Fred
Enseignant
Inscription : juillet 2006
Messages : 1 324
Détails du profil
Informations personnelles :
Nom : Homme Fred
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : juillet 2006
Messages : 1 324
Points : 1 823
Points : 1 823
Sinon strtol, non ça le fait pas?

Code :
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)
fred1599 est déconnecté   Envoyer un message privé Réponse avec citation 02
Vieux 15/01/2013, 18h47   #7
Bktero
Expert Confirmé Sénior
 
Avatar de Bktero
 
Ingénieur systèmes embarqués
Inscription : juin 2009
Messages : 1 717
Détails du profil
Informations personnelles :
Âge : 25
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Ingénieur systèmes embarqués
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2009
Messages : 1 717
Points : 4 217
Points : 4 217
@Fred : comme je l'ai dit, le but du jeu pour lui est sûrement de recoder une fonction équivalente à strtol() justement ^^

@mith06 :
Citation:
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
__________________
Si Code::Blocks vous dit undefined reference to 'socket@12', cela signifie que vous avez un problème d'édition des liens. Allez dans Projects / Build Options / Linker Settings / Add et renseigner ici les .a qui vont bien. Exemple pour les sockets : C:\Program Files\CodeBlocks\MinGW\lib\libws2_32.a

Pour les adeptes du langage SMS, allez ici et ramenez la traduction française ^^

Pour vos problèmes d'embarqué, utilisez le forum dédié !
Bktero est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/01/2013, 22h38   #8
Luke spywoker
Membre éclairé
 
Avatar de Luke spywoker
 
Homme
Etudiant informatique autodidacte
Inscription : juin 2010
Messages : 591
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Etudiant informatique autodidacte

Informations forums :
Inscription : juin 2010
Messages : 591
Points : 370
Points : 370
Merci pour vos réponses,
Citation:
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 :
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...
Blog: http://3dcyberspace.unblog.fr/
Site: Sanctuaire cybernétique
Luke spywoker est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2013, 11h26   #9
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 437
Détails du profil
Informations personnelles :
Nom : Homme Patrick Gonord
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Enseignement

Informations forums :
Inscription : juin 2005
Messages : 5 437
Points : 12 977
Points : 12 977
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 :
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 !
diogene est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/01/2013, 10h58   #10
Médinoc
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 22 396
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France

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

Informations forums :
Inscription : septembre 2005
Messages : 22 396
Points : 32 049
Points : 32 049
Envoyer un message via MSN à Médinoc
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 :
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 :
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.
Médinoc est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 18/01/2013, 11h14   #11
liberforce
Membre Expert
 
Homme
Développeur informatique
Inscription : juin 2009
Messages : 1 040
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 040
Points : 1 526
Points : 1 526
Dans ce cas là, autant écrire directement:

Code C :
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.
liberforce est déconnecté   Envoyer un message privé Réponse avec citation 02
Vieux 18/01/2013, 11h27   #12
Médinoc
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 22 396
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France

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

Informations forums :
Inscription : septembre 2005
Messages : 22 396
Points : 32 049
Points : 32 049
Envoyer un message via MSN à Médinoc
Ç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.
Médinoc est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 24/01/2013, 13h19   #13
Luke spywoker
Membre éclairé
 
Avatar de Luke spywoker
 
Homme
Etudiant informatique autodidacte
Inscription : juin 2010
Messages : 591
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Etudiant informatique autodidacte

Informations forums :
Inscription : juin 2010
Messages : 591
Points : 370
Points : 370
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 :
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...
Blog: http://3dcyberspace.unblog.fr/
Site: Sanctuaire cybernétique
Luke spywoker est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2013, 14h33   #14
Bktero
Expert Confirmé Sénior
 
Avatar de Bktero
 
Ingénieur systèmes embarqués
Inscription : juin 2009
Messages : 1 717
Détails du profil
Informations personnelles :
Âge : 25
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Ingénieur systèmes embarqués
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2009
Messages : 1 717
Points : 4 217
Points : 4 217
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 :
while ((c=getchar()) != '\n')
Donc après cette boucle, c contient \n.

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

Citation:
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().
__________________
Si Code::Blocks vous dit undefined reference to 'socket@12', cela signifie que vous avez un problème d'édition des liens. Allez dans Projects / Build Options / Linker Settings / Add et renseigner ici les .a qui vont bien. Exemple pour les sockets : C:\Program Files\CodeBlocks\MinGW\lib\libws2_32.a

Pour les adeptes du langage SMS, allez ici et ramenez la traduction française ^^

Pour vos problèmes d'embarqué, utilisez le forum dédié !
Bktero est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 25/01/2013, 12h58   #15
Luke spywoker
Membre éclairé
 
Avatar de Luke spywoker
 
Homme
Etudiant informatique autodidacte
Inscription : juin 2010
Messages : 591
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Etudiant informatique autodidacte

Informations forums :
Inscription : juin 2010
Messages : 591
Points : 370
Points : 370
Merci pour la réponse,
Citation:
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 :
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 :
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 :
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.

Citation:
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...
Blog: http://3dcyberspace.unblog.fr/
Site: Sanctuaire cybernétique
Luke spywoker est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2013, 13h41   #16
Bktero
Expert Confirmé Sénior
 
Avatar de Bktero
 
Ingénieur systèmes embarqués
Inscription : juin 2009
Messages : 1 717
Détails du profil
Informations personnelles :
Âge : 25
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Ingénieur systèmes embarqués
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2009
Messages : 1 717
Points : 4 217
Points : 4 217
Citation:
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).


Citation:
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 ^^)


Citation:
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").


Citation:
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 !

Citation:
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.


Citation:
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 !

Citation:
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.
__________________
Si Code::Blocks vous dit undefined reference to 'socket@12', cela signifie que vous avez un problème d'édition des liens. Allez dans Projects / Build Options / Linker Settings / Add et renseigner ici les .a qui vont bien. Exemple pour les sockets : C:\Program Files\CodeBlocks\MinGW\lib\libws2_32.a

Pour les adeptes du langage SMS, allez ici et ramenez la traduction française ^^

Pour vos problèmes d'embarqué, utilisez le forum dédié !
Bktero est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2013, 14h11   #17
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 437
Détails du profil
Informations personnelles :
Nom : Homme Patrick Gonord
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Enseignement

Informations forums :
Inscription : juin 2005
Messages : 5 437
Points : 12 977
Points : 12 977
Citation:
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 !
diogene est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 25/01/2013, 15h13   #18
Médinoc
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 22 396
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France

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

Informations forums :
Inscription : septembre 2005
Messages : 22 396
Points : 32 049
Points : 32 049
Envoyer un message via MSN à Médinoc
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.
Médinoc est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 26/01/2013, 13h09   #19
leternel
Expert Confirmé
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 220
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

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

Informations forums :
Inscription : juin 2007
Messages : 1 220
Points : 2 596
Points : 2 596
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.
  • La plus sotte des questions est celle qu'on ne pose pas.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 15h44.


 
 
 
 
Partenaires

Hébergement Web