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 :

Convertir un nombre d'une chaine de caratrère en un nombre


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 256
    Par défaut Convertir un nombre d'une chaine de caratrère en un nombre
    Bonjour tout le monde,

    Je débute en C, et je suis en train de faire un petit jeu "plus ou moins".
    Le programme marche très bien si on lui rentre des chiffres, mais il fais une boucle infinie si on rentre des caractères.

    Donc, ce que je veut maintenant arriver à faire, c'est pouvoir tester ce que rentre l'utilisateur, et lui afficher par exemple "veuillez rentrer un nombre svp".
    La où je bloque, c'est que les caractères sont enregistrés en mémoire comme des nombres, donc comment détécter si l'utilisateur à rentré un caractère ou un nombre ?

    Sinon, avez-vous un bout de code qui ressemble à ce que je veut faire pour que je vois comment aurais fait un non-débutant ?

    Merci.
    Pierre.

    PS : si ça peut servir, voilà mon code actuel :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h> // pour la génération du nombre aléatoire
     
    int main(void)
    {
      printf("Jeu \"Plus ou moins\"\n");
      printf("Essayez de trouver le plus rapidement possible le nombre entre 0 et 101 :\n\n");
     
      srand(time(NULL));
      #define max 100
      #define min 1
      char nbATrouver=(rand() % (max - min + 1)) + min;
     
      int nombre, i;
     
      for (i=1; nombre!=nbATrouver; ++i)
      {
        printf("Essai %ld : ", i);
        scanf("%ld", &nombre);
     
        if (nombre==nbATrouver)
        {
          printf("\nBravo !\n\n");
        }
        else if (nombre<nbATrouver)
        {
          printf("Trop petit\n\n", nombre);
        }
        else
        {
          printf("Trop grand\n\n", nombre);
        }
      }
     
      system("PAUSE");
      return 0;
    }

  2. #2
    Membre expérimenté Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Par défaut
    Faut pas utiliser scanf(), en tout cas pas de cette façon-là. Ce n'est pas une fonction facile à utiliser, pour débuter il vaut mieux utiliser fgets(), puis convertir la chaîne lue en nombre avec, par exemple, strtol().

  3. #3
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Voici une version corrigée avec des remarques en commentaires...
    Poses des questions si tu ne comprends pas quelque chose...

    Jc

    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
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h> // pour la génération du nombre aléatoire
     
    /* -fy- Constantes hors du main, c'est plus joli et en majuscules... */
    #define MAX 100
    #define MIN 1
     
    int main(void)
    {
        char nbATrouver, buf[16];
     
        /* -fy- on met nombre a une valeur qui ne peut pas etre nbATrouver */
        int nombre = MIN-1, i;
     
        printf("Jeu \"Plus ou moins\"\n");
        printf("Essayez de trouver le plus rapidement possible le nombre entre 0 et 101 :\n\n");
     
        srand(time(NULL));
        nbATrouver=(rand() % (MAX - MIN + 1)) + MIN;
     
        /* -fy- On ne sait pas combien d'iterations -> while */
        i=1;
        while(nombre!=nbATrouver)
        {
            /* -fy- i est un int donc %d pas %ld */
            printf("Essai %d : ", i);
     
            /* -fy- scanf est deconseille, on utilise fgets */
            if(fgets(buf,sizeof(buf),stdin)==NULL)
                return EXIT_FAILURE;
            /* On regarde si on a reussi a avoir une ligne entiere */
            if(strchr(buf,'\n')==NULL)
            {
                printf("Chaine entree trop grande\n");
                return EXIT_FAILURE;
            }
            else 
            {   
                nombre = strtol(buf,NULL,0);
     
                if (nombre==nbATrouver)
                {
                    printf("\nBravo !\n\n");
                }
                else if (nombre<nbATrouver)
                {
                    printf("Trop petit\n\n");
                }
                else
                {
                    printf("Trop grand\n\n");
                }
                ++i;
            }
        }
     
        /* -fy- Ce n'est pas portable 
           system("PAUSE"); */
     
        return EXIT_SUCCESS;
    }

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 256
    Par défaut
    OK, merci pour ces réponses, j'ai un truc plus ou moins urgent à faire et je regarde ça plus en détail après, je vais avoir quelques questions.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 256
    Par défaut
    Bon, je viens de regarder tout ça, ça marche, mais il y as quelques trucs que je n'arrive pas à comprendre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(fgets(buf, sizeof(buf), stdin)==NULL)
    return EXIT_FAILURE;
    1. Ici, on lis dans l'entrée standard, ça c'est ok.
    Mais ce que je ne comprend pas c'est que le if(fgets...) est juste après l'affichage de "Essai x : ", donc fgets attend de trouver un \n pour passer au reste ?

    2. On teste que fgets a bien réussis à lire quelque chose dans stdin, mais est-il possible que ça n'y arrive pas ? est-ce que c'est pour les OS exotiques ?

    3. Le code ne plante plus quand on rentre des caractères, mais est-il possible des les détécter (pour mettre par exemple : "veuillez entrer un nombre") ?
    Faut il utiliser des expressions régulières comme en PHP ?

    4. Pour remplacer le system("PAUSE"); j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    printf("Validez pour quitter\n");
    fflush(stdin);
    getchar();
    Mais la fonction getchar s'arrète seulement si on appuis sur entrée, quelle est la fonction qui s'arrête avec l'appuis sur n'importe quelle touche ?

    5. Pour finir, comment capter quand l'utilisateur appuis sur la touche echap ?


    Merci beaucoup.
    Pierre.

  6. #6
    Membre expérimenté Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Par défaut
    Citation Envoyé par Pierre.g
    1. Ici, on lis dans l'entrée standard, ça c'est ok.
    Mais ce que je ne comprend pas c'est que le if(fgets...) est juste après l'affichage de "Essai x : ", donc fgets attend de trouver un \n pour passer au reste ?
    On peut dire ça comme ça.

    Citation Envoyé par Pierre.g
    2. On teste que fgets a bien réussis à lire quelque chose dans stdin, mais est-il possible que ça n'y arrive pas ? est-ce que c'est pour les OS exotiques ?
    Pourquoi exotique ?
    Il suffit de saisir un EOF et fgets() interprète cela comme une fin de fichier, comme cette fonction lit un flux quelconque (donc potentiellement, un fichier), cela permet de détecter la fin de lecture.

    Tu peux simuler ce comportement très simplement : sous Unix il te suffit de taper ctrl+d.
    Sur Windows, il suffit de taper ctrl+z, puis [entrée] (contrainte : sous windows un EOF sur le flux d'entrée standard n'est détecté que s'il est le premier caractère de la ligne lue.)

    fgets() peut aussi retourner NULL si une erreur s'est produite (la détection d'un EOF n'étant pas une erreur).
    Au lieu de retourner EXIT_FAILURE lorsque fgets() renvoie NULL, il vaut mieux vérifier si une erreur a eu lieu à l'aide de ferror(). Si ce n'est pas le cas, on peut continuer le programme normalement.

    Citation Envoyé par Pierre.g
    3. Le code ne plante plus quand on rentre des caractères, mais est-il possible des les détécter (pour mettre par exemple : "veuillez entrer un nombre") ?
    Faut il utiliser des expressions régulières comme en PHP ?
    Ce ne sont pas des expressions régulières (hélas), mais des patterns particuliers.
    Tu en sauras plus en lisant attentivement l'aide des fonctions ...scanf().

    Citation Envoyé par Pierre.g
    4. Pour remplacer le system("PAUSE"); j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    printf("Validez pour quitter\n");
    fflush(stdin);
    getchar();
    Mais la fonction getchar s'arrète seulement si on appuis sur entrée, quelle est la fonction qui s'arrête avec l'appuis sur n'importe quelle touche ?
    Non : fflush() ne s'utilise qu'avec des flux d'écriture !
    Cette fonction a un comportement indéfini sur des flux tels que stdin.

    Quant à détecter l'appui quelconque d'une touche, il n'y a pas de méthode standard en C pour faire ça.

    Citation Envoyé par Pierre.g
    5. Pour finir, comment capter quand l'utilisateur appuis sur la touche echap ?
    Pas de méthode standard, donc. Mais avec les bibliothèques que l'on trouve pour tel ou tel OS, tu trouveras que le code de la touche echap est, en général, 27.

  7. #7
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    il vaut mieux vérifier si une erreur a eu lieu à l'aide de ferror()
    D'ailleurs comment savoir les erreurs que peut lever "fgets"?
    Existe il une liste pour chaque fonction des erreurs potentielles?

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

Discussions similaires

  1. Extraire un nombre dans une chaine
    Par SIGOliv dans le forum Access
    Réponses: 16
    Dernier message: 13/03/2006, 15h44
  2. [MySQL] extraire des nombre d'une chaine de caractères et addition
    Par Yotho dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 04/03/2006, 16h54
  3. Réponses: 4
    Dernier message: 20/02/2006, 00h33
  4. Récuperer un nombre dans une chaine de caractère
    Par ColonelHati dans le forum C
    Réponses: 4
    Dernier message: 27/04/2005, 14h50
  5. [LG]Extraire des nombres d'une chaine
    Par audreym31 dans le forum Langage
    Réponses: 4
    Dernier message: 18/01/2004, 21h24

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