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 :

Instruction ignorée ? Calcul de périmètre d'un cercle


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 1
    Par défaut Instruction ignorée ? Calcul de périmètre d'un cercle
    Bonjour à tous,
    Voilà mon problème je débute en C et je bug sur un exercice..
    Je dois rédiger un petit programme qui permet de calculer le périmètre d'un cercle voici le code que j'ai rédigé :

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
        float pi = 3.14;
        float rayon = 0,perimetre = 0, aire = 0;
       char reponse;
        printf("bonjour\n");
        printf("entrez la valeur du valeur du rayon svp\n");
        scanf("%f",& rayon);
        printf( "souhaiter vous obtenir le perimetre(O/N)?");
       scanf(" %c",& reponse);
        if(reponse == O)
       {
           perimetre = 2*pi*rayon;
           printf(" la valeur du perimetre du cercle de rayon %f est %f\n",rayon,perimetre);
       }
     
     
       printf("souhaitez vous obtenir l air du cercle (O/N)?");
     
       scanf("%c",&reponse);
     
        if(reponse == O)
        {
            aire = pi*rayon*rayon ;
     
            printf("la valeur de l air du cercle est %f\n",aire);
     
     
        }
        printf(" merci d avoir utiliser ce programme bonne journee");
    }
    Tout se passe bien au départ mais après la première instruction le programme s'enchaîne sans me demander si je veux calculer l'air ( if(reponse == O) ) en gros cette instruction est ignorer si je peux dire ça ainsi et je ne vois pas trop pourquoi..
    Merci d'avance...

  2. #2
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2012
    Messages : 82
    Par défaut
    Bonjour,

    Vu que ta variable reponse est un caractère il faut soit que tu l'as compare à un nombre en te reportant sur le tableau ASCII, soit que tu l'as compare à 'O'.

  3. #3
    Modérateur

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

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Ce code ne peut pas compiler sans erreur : /home/pierre/Documents/TestsC/main.c|14|error: ‘O’ undeclared (first use in this function)|En modifiant pour avoir 'O' en rajoutant un petit printf, tu comprendras le problème :
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(void)
    {
        float pi = 3.14;
        float rayon = 0,perimetre = 0, aire = 0;
        char reponse;
        printf("bonjour\n");
        printf("entrez la valeur du valeur du rayon svp\n");
        scanf("%f",& rayon);
        printf( "souhaiter vous obtenir le perimetre(O/N)?\n");
     
        scanf(" %c",& reponse);
        printf("Caractere lu : [%c]", reponse); // BKTERO
     
     
        if(reponse == 'O')
        {
            perimetre = 2*pi*rayon;
            printf(" la valeur du perimetre du cercle de rayon %f est %f\n",rayon,perimetre);
        }
     
     
        printf("souhaitez vous obtenir l air du cercle (O/N)?\n");
     
        scanf("%c",&reponse);
        printf("Caractere lu : [%c]", reponse); // BKTERO
     
        if(reponse == 'O')
        {
            aire = pi*rayon*rayon ;
            printf("la valeur de l air du cercle est %f\n",aire);
        }
     
        printf("\n\nmerci d avoir utiliser ce programme bonne journee");
     
        return 0;
    }
    Quand tu entres 'O' suivi de ENTREE, le buffer clavier contient 'O' et '\n' mais le premier scanf (pour les caractères, donc le 2e du programme) ne le consomme pas, cet '\n'. Le second le lit et s'arrête là. Scanf est une fonction délicate, il y a un tutoriel bien fait dans la rubrique cours C, lis-le.

    Si tu souhaites récupérer un seul caractère du clavier, il faut mieux utiliser getchar().

    Attention aussi à scanf pour récupérer l'entier, il reste aussi un '\n' dans le buffer clavier (qui pose soucis pour utiliser getchar() juste derrière).

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

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Lorsque tu fais un scanf(), l'entrée est lue de la façon suivante :
    - les caractères <blancs> (au sens de isspace() donc également le '\n') sont lus et ignorés, sauf pour les formats "%c", "%n" et "%[...".
    - la valeur est lue et s'arrête dès que le caractère ne correspond plus au format spécifié
    Le reste de la ligne reste en attente de traitement.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    scanf("%f",&a);
    scanf("%f",&b);
    avec une entrée 12345 6789 <return> ou une entrée 12345 <return> 6789 <return> donnera a==12345 et b==6789

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    scanf("%f",&a);
    scanf("%c",&b);
    avec une entrée 12345x <return> donnera a==12345 et b=='x' sans besoin d'une entrée supplémentaire
    avec une entrée 12345 x <return> donnera a==12345 et b==' ' sans besoin d'une entrée supplémentaire
    et l'entrée 12345<return> donnera a==12345 et b=='\n' sans besoin d'une entrée supplémentaire

    Si on veut s'affranchir de ce comportement, il faut s'assurer que la ligne est entièrement consommée avant la lecture en "%c". Par exemple,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf("%f%*[^\n]%*c", &a);
    le %*[^\n] lit tous les caractères différents (à cause du ^) de '\n' et les ignorent (à cause de *)
    le %*c lit le caractère '\n' et l'ignore.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Salut
    Bienvenue dans ce monde. A la fois simple et complexe.
    Donc comme d'autres te l'ont écrit, le vrai problème vient de scanf et de sa façon de gérer le buffer stdin qui donc n'est pas du tout destiné à gérer les saisies humaines mais qu'on est bien obligé d'utiliser quand on débute car on n'a rien d'autre.

    Maintenant voici le même exercice mais utilisant une autre méthode plus robuste pour faire saisir des valeurs
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
        float pi = 3.14;
        float rayon = 0;
        char saisie[101];
        char reponse;
     
        printf("bonjour\n");
        while(1)
        {
            printf("entrez la valeur du rayon svp ? "); fflush(stdout);
            fgets(saisie, 101, stdin);
            if (sscanf(buffer, "%f", &rayon) == 1 && rayon >= 0) break;
            printf("saisie incorrecte - recommencez\n");
        }
     
        printf("souhaitez vous obtenir le périmètre (O/N)? "); fflush(stdout);
        fgets(saisie, 101, stdin);
        sscanf(buffer, "%c", &reponse);
        if(reponse == 'O' || reponse == 'o')
            printf("la valeur du périmètre du cercle de rayon %f est %f\n", rayon, 2*pi*rayon);
     
        printf("souhaitez vous obtenir l'aire (O/N)? "); fflush(stdout);
        fgets(saisie, 101, stdin);
        sscanf(buffer, "%c", &reponse);
        if(reponse == 'O' || reponse == 'o')
            printf("la valeur de l'aire du cercle de rayon %f est %f\n", rayon, pi*rayon*rayon);
        printf("merci d'avoir utilisé ce programme et bonne journée\n");
    }
    Ce programme n'est pas à l'épreuve du couillon qui rentrerait 102 caractères lors de la saisie mais peut gérer les cas les plus courants. Evite cependant de le présenter à ton prof comme étant le tien car il ne sera pas dupe. Je ne l'ai pas écrit pour te permettre de briller temporairement par une tricherie mais pour que tu puisses mieux comprendre les subtilités de la saisie et t'améliorer de façon à ce que tu puisses briller naturellement tout au long de ta vie. Et pour ce faire, je te suggère aussi de te documenter sur fgets() et sur sscanf().

    PS: le fflush(stdout) est là pour que printf() affiche son texte immédiatement sans attendre le vidage automatique. Mais on éviterait ce souci en remplaçant les printf("question") par des fputs("question", stdout)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre émérite
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Par défaut
    Citation Envoyé par Sve@r
    PS: le fflush(stdout) est là pour que printf() affiche son texte immédiatement sans attendre le vidage automatique. Mais on éviterait ce souci en remplaçant les printf("question") par des fputs("question", stdout)...
    stdin étant bufferisé par ligne, utiliser fputs ne changera pas grand chose par rapport à printf, car il n'y a pas de '\n' ajoutés automatiquement, comme c'est le cas avec puts.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Kirilenko Voir le message
    stdin étant bufferisé par ligne, utiliser fputs ne changera pas grand chose par rapport à printf, car il n'y a pas de '\n' ajoutés automatiquement, comme c'est le cas avec puts.
    Exact, erreur de ma part, fputs() n'imprime pas non plus de façon immédiate et donc nécessite lui-aussi un fflush(stdout) si on veut voir son action se faire immédiatement (et on parle bien de stdout et non stdin)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Modérateur

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

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Si on met un \n à la fin de la chaine de printf(), est-ce que cela suffit (si c'est juste une histoire de retour à la ligne) ?

    D'ailleurs, je ne met jamais de fflush(stdout) dans mes programmes. Dans quels cas pourrais-je avoir des soucis ?

  9. #9
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    L'utilisation d'un '\n' force le vidage du tampon, donc ça suffit.
    Pour l'utilisation du ffflush(stdout), je n'ai pas d'exemples en tête, mais j'ai déjà été obligé de l'utiliser (je ne me souvient plus du contexte).

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bktero Voir le message
    D'ailleurs, je ne met jamais de fflush(stdout) dans mes programmes. Dans quels cas pourrais-je avoir des soucis ?
    Uniquement (si tu n'utilises pas QtCreator) dans un cas similaire à celui-ci
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
        printf("Hello...");
        sleep(15);
        printf("...world\n");
    }
    Ton "Hello" ne sortira réellement à l'écran qu'après les 15 secondes (et donc tu auras "Hello......world" d'un coup...)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. erreur de calcule de périmètre de cercle
    Par benmia dans le forum Général Java
    Réponses: 1
    Dernier message: 07/06/2015, 11h38
  2. Calculer le périmètre d'un terrain avec le GPS du mobile
    Par auxiliaire dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 18/12/2014, 09h53
  3. Compacité: calcul aire+périmètre
    Par nadou114 dans le forum Images
    Réponses: 7
    Dernier message: 24/11/2010, 07h47
  4. Réponses: 5
    Dernier message: 25/08/2010, 18h13
  5. Calcul coordonnées centre d'un cercle passant par deux points
    Par acecel dans le forum Mathématiques
    Réponses: 12
    Dernier message: 13/04/2010, 14h47

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