Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 13/07/2016, à 18:33

Hitec-user

[RESOLU] Langage C : code ascii d'un entier

Bonjour à tous,

Je suis en train d'apprendre le C, et dans le cadre d'un exercice que j'essaye d'améliorer, j'ai besoin de savoir comment récupérer le code ascii d'un chiffre (nombre entier) afin de vérifier que l'utilisateur du programme a bien saisi un chiffre (et par extension un nombre en contrôlant la variable chiffre par chiffre) et pas une lettre ou autre chose.

Exemple de code de base:

#include<stdio.h>
#include<ctype.h> /* C'est peut-être là, mais les fonctions comme isdigit() se basent sur le type char ce qui ne correspond pas à ce que je cherche, opérations sur les variables numériques à suivre. */

int bonne_saisie(int x);

int main() {

  int a;
  while (bonne_saisie(a)!=1) {
    printf("Saisissez un chiffre entre 0 et 9 :\n");
    scanf("%d", &a);
    printf("\"a\" vaut %d.\n", a);
  }
  return 0;
}

int bonne_saisie(int x) {

  int valide=0;

  /* bout de code qui vérifie le code ascii de x */

  return valide;
}

Merci d'avance pour votre aide.

Dernière modification par Hitec-user (Le 23/07/2016, à 12:23)

Hors ligne

#2 Le 13/07/2016, à 19:25

lann

Re : [RESOLU] Langage C : code ascii d'un entier

La table ASCII : http://ascii-code.com/
Donc le 0, c'est 48
ainsi de suite

Hors ligne

#3 Le 13/07/2016, à 20:37

Hitec-user

Re : [RESOLU] Langage C : code ascii d'un entier

Bonsoir lann,

Merci pour la réponse, mais il y a un malentendu: ce n'est pas la table des codes ascii que je cherche, j'ai même fait un programme qui me l'affiche dans le terminal quand j'ai besoin (trop facile cool ).

Le problème que je pose, c'est que je demande à l'utilisateur de rentrer un nombre (à 1 chiffre pour commencer) capturé par scanf(), puis j'ai besoin de vérifier qu'il a bien saisi un nombre et pas autre chose, pour cela, j'ai besoin de récupérer le code ascii de la valeur contenue dans la variable (on reste sur 1 chiffre pour le moment) qui est déjà de type int pour la comparer justement avec les valeurs du tableau.
Mon exemple de code est, je l'espère explicite.

En clair, je veux vérifier si le code ascii de la variable int se situe bien entre 48 et 57, sinon, je redemande de saisir une valeur valide.

Bien cordialement.

Dernière modification par Hitec-user (Le 13/07/2016, à 20:42)

Hors ligne

#4 Le 13/07/2016, à 21:10

claudius01

Re : [RESOLU] Langage C : code ascii d'un entier

Bonsoir,

Bienvenu Hitec-user sur ce forum et dans l’écosystème de ce puissant Langage C ;-)
Pour ton problème, il existe une série de macros définies comme suit: isalpha, isalnum, isascii, etc. and Co à coller juste derrière ton commentaire:

   ...
   /* bout de code qui vérifie le code ascii de x */
   if (isdigit(x)) {
      /* x est un chiffre entre entre '0' et '9' */
      valide = 1;
   }
   ...

NB: C'est bizarre, tu avais déjà inclus le <ctype.h> et je ne comprends pas ton commentaire sur la même ligne ?:-)

Dernière modification par claudius01 (Le 13/07/2016, à 21:12)

Hors ligne

#5 Le 13/07/2016, à 21:50

Hitec-user

Re : [RESOLU] Langage C : code ascii d'un entier

Bonsoir Claudius01,

C'est justement que j'avais déjà testé isdigit(x) car je me doutait que la réponse pouvais être parmi les fonctions de ctype.h, mais celle-ci ne fonctionne que si la variable est de type char, mais ne fonctionne pas sur les type int car elle prend le nombre lui-même et non son code ascii. Je vais tester les autres que tu as cité pour voir ce que ça donne.

Hors ligne

#6 Le 13/07/2016, à 21:57

claudius01

Re : [RESOLU] Langage C : code ascii d'un entier

Effectivement, j'ai écrit une grosse bêtise car je ne n'utilise jamais scanf() qui est d'ailleurs à bannir, car s’arrêta de parser dès qu'un caractère non numérique sera saisi du fait du %d ...

Utilise donc une saisie caractère avec %c, %s ou mieux avec autre méthode comme getchar(), puis passer le résultat dans un strtol() qui peut travailler dans n'importe qu'elle base (ici, cela sera la base 10 ;-)

Dernière modification par claudius01 (Le 13/07/2016, à 22:10)

Hors ligne

#7 Le 14/07/2016, à 08:53

grigouille

Re : [RESOLU] Langage C : code ascii d'un entier

Utilise strtol et vérifie s'il y a une erreur.


Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#8 Le 23/07/2016, à 12:21

Hitec-user

Re : [RESOLU] Langage C : code ascii d'un entier

Bonjour Claudius et les autres,

J'ai donc réussi à effectuer le test pour contrôler la validité de la saisie par l'utilisateur. Mais comme je fais saisir un nombre entre 1 et 1000, j'ai du prendre pour variable un tableau de type char (voir la fonction lire_choix dans le code ci-dessous. Mon test fonctionne. isdigit ne m'a pas servi, j'ai préféré faire le test "à la main". Je cale maintenant sur la transformation de la chaîne de caractère (chaîne de chiffres) en nombre mathématique. J'ai fait un autre post pour cela ici.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<math.h>

/* Variables communes */
int nb_alea=0;
char saisie[4];

/* Index des fonctions */
void affiche_regle(); /* Affiche :e titre et la règle du jeu */
void choisir_nombre(); /* Choisit un nombre aléatoire pour nb_alea */
void lire_choix(); /* Capture la saisie du clavier et le stocke dans 'saisie' */
void clean(const char *buffer, FILE *fp); /* pour la purge de stdin, utilisé dans lire_choix */
int saisie_valide(); /* Vérifie si chaque caractère de 'saisie' est bien un chiffre */
int convertir_saisie(); /* Lit la chaine 'saisie' et la convertit en long int */
int result_essai(int nombre); /* Compare 'nombre' et 'nb_alea' => rend -1 si c'est moins, +1 si c'est plus et +2 si c'est = */
void affiche_result(int resultat); /* dit si c'est >, <, si la partie est gagnée ou perdue(essais épuisés) */

/* Programme principal */
int main() {

  int nb_essais=0, nombre=0, resultat=0, fini=0;

  affiche_regle();
  choisir_nombre();

  while (fini==0) {
    printf("Saisissez un nombre ebtre 1 et 1000 : ");

    lire_choix();

    while (saisie_valide()==0) {
      printf("Saisie invalide... entrez un nombre entre 1 et 1000 : ");
      lire_choix();
    }

    nombre=convertir_saisie();
    resultat=result_essai(nombre);

    if (resultat==2 || nb_essais>=15)
      fini=1;

    affiche_result(resultat);
    nb_essais++;
  }

  return 0;
}

/* Sous-programmes */
/*******************************************************/
void affiche_regle() {

  printf("\n");
  printf("                    ****************************************\n");
  printf("                    *    Jeu de recherche stratégique      *\n");
  printf("                    *   réalisé par Sylvio Desjardins%d.    *\n", 169);
  printf("                    ****************************************\n");
  printf("\n");
  printf("                 Un nombre entre 1 et 1000 est tiré au hazard,\n");
  printf("                 vous devez le trouver en moins de 15 essais.\n");
  printf("\n");
}

/*******************************************************/
void choisir_nombre() {

  srand(time(NULL));

  nb_alea=1+(rand() % 999);
}

/*******************************************************/
void lire_choix() {

  fgets(saisie, sizeof(saisie), stdin);
  clean(saisie, stdin);

}

/*******************************************************/
void clean(const char *buffer, FILE *fp) {

  char *p=strchr(buffer, '\n');
  if (p!=NULL)
    *p=0;
  else {
    int c;
    while ((c=fgetc(fp))!='\n' && c!=EOF);
  }
}

/*******************************************************/
int saisie_valide() {

  int i=0;
  int test=1;

  while (i<sizeof(saisie) && test==1) {
    if (((int)saisie[i]<48 || (int)saisie[i]>57) && (int)saisie[i]!=0)
      test=0;
  }
  return test;
}

/*******************************************************/
int convertir_saisie() {

  long int nombre=0;
  int *sr;

  nombre=strtol(saisie, &sr, 10);

  return (int)nombre;
}
/*******************************************************/
int result_essai(int nombre) {

  int r=0;

  if (nombre==nb_alea)
    r=2;
  else if (nombre>nb_alea)
    r=-1;
  else if (nombre<nb_alea)
    r=1;
  else {
    printf("ERREUR, valeur eronnée pour \'nombre(=%i)\' ou \'nb_alea(=%i)\'\n", nombre, nb_alea);
    exit(0);
  }

  return r;
}

/*******************************************************/
void affiche_result(int resultat) {

  if (resultat==2)
    printf("Bravo, vous avez gagné, la réponse est bien %i.\n", nb_alea);
  else if (resultat==-1)
    printf("C'est moins.\n");
  else if (resultat==1)
    printf("C'est plus.\n");
  else {
    printf("affiche_result : Valeur erronée pour \'resultat\'(=%d).\n", resultat);
    exit(0);
  }
}

Le sujet actuel est résolu.
Merci donc pour votre aide.

Hors ligne

#9 Le 23/07/2016, à 13:15

grigouille

Re : [RESOLU] Langage C : code ascii d'un entier

Attention :

114:25: warning: passing argument 2 of ‘strtol’ from incompatible pointer type [-Wincompatible-pointer-types]
   nombre=strtol(saisie, &sr, 10);

Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#10 Le 23/07/2016, à 13:17

grigouille

Re : [RESOLU] Langage C : code ascii d'un entier

int saisie_valide() {

  int i=0;
  int test=1;

  while (i<sizeof(saisie) && test==1) {
    if (((int)saisie[i]<48 || (int)saisie[i]>57) && (int)saisie[i]!=0)
      test=0;
  }
  return test;
}

i reste à 0.


Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#11 Le 25/07/2016, à 16:43

Hitec-user

Re : [RESOLU] Langage C : code ascii d'un entier

En effet, j'ai oublié le i++;
Voici le code corrigé pour saisie_valide:

int saisie_valide() {

  int i=0;
  int test=1;

  while (i<sizeof(saisie) && test==1) {
    if (((int)saisie[i]<48 || (int)saisie[i]>57) && (int)saisie[i]!=0)
      test=0;
  }
  return test;
}

J'ai bien vu le message

114:25: warning: passing argument 2 of ‘strtol’ from incompatible pointer type [-Wincompatible-pointer-types]
   nombre=strtol(saisie, &sr, 10);

mais je ne sais justement pas comment corriger ça, c'est à dire comment faire prendre à strtol la valeur de 'saisie' telle qu'elle s'affiche dans un printf("%s", saisie). J'ai aussi corrigé la longueur de saisie, mais c'est mineur.
On se retrouve sur l'autre fil.
Encore merci.

Hors ligne