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 :

verification d'entrée en utilisant while


Sujet :

C

  1. #1
    Candidat au Club
    Inscrit en
    Octobre 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 3
    Par défaut verification d'entrée en utilisant while
    Salut à touuus !
    Je cherche de l’aide pour :
    Écrire un programme qui fait la somme de deux nombres de types (int) et vérifie d’abord qu’ils sont de même type (int).

    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
    #include<stdio.h>
    #include<conio.h>
    int main()
    {
    int a,b;
    bool v;
    v=scanf("%d",&a);
    if(v) 
    {
    v=scanf("%d",&b);
    if(v)
    printf("%d+%d=%d\n",a,b,a+b);
    else
    printf("ce que vous avez entré n'est pas de type int \a ! \n");
    }
    else
    printf("ce que vous avez entré n'est pas de type int \a ! \n");
    getch();
    return 0;
    }
    Je veux que me le faire avec la boucle while ,(tant que l’utilisateur ne tape pas un nombre de type int reste toujours de la boucle ).
    Et je serais très reconnaissant.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    D'abord, scanf() ne retourne pas un bool mais un int.
    Vous devriez décaler les lignes à l'intérieur d'un bloc accolades.

    Donc vous avez 2 questions
    1- tester si le nombre entré par l'utilisateur est un int.
    Il n'existe pas de fonction C pour faire cela. Donc la seule solution est de lire ce qu'a entré l'utilisateur et tester si cela correspond bien à un nombre entier inférieur à 32767 si vous êtes en 32 bits.
    2- boucler avec while, tant que etc...
    La syntaxe de while est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(condition)
    { 
    ...  traitement
    }
    Tant que condition est vrai, c'est à dire différent de zéro, le traitement va s'exécuter.
    Donc, il faudra en sortir, soit en mettant condition à false, ou zéro, soit en utilisant le mot clé break.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par raymond_prg Voir le message
    Salut à touuus !
    Je cherche de l’aide pour :
    Écrire un programme qui fait la somme de deux nombres de types (int) et vérifie d’abord qu’ils sont de même type (int).

    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
    #include<stdio.h>
    #include<conio.h>
    int main()
    {
    int a,b;
    bool v;
    v=scanf("%d",&a);
    if(v) 
    {
    v=scanf("%d",&b);
    if(v)
    printf("%d+%d=%d\n",a,b,a+b);
    else
    printf("ce que vous avez entré n'est pas de type int \a ! \n");
    }
    else
    printf("ce que vous avez entré n'est pas de type int \a ! \n");
    getch();
    return 0;
    }
    Je veux que me le faire avec la boucle while ,(tant que l’utilisateur ne tape pas un nombre de type int reste toujours de la boucle ).
    Et je serais très reconnaissant.
    Ben déjà faut pas utiliser scanf. Parce que scanf attend une entrée "formatée" et que ce que tape l'utilisateur est tout sauf formaté. Et ce que scanf ne sait pas gérer ben il le laisse dans le clavier ce qui va ensuite polluer les saisies suivantes.
    scanf est montré aux débutants parce qu'il leur faut une fonction input et que c'est la plus rapide à expliquer et à mettre en oeuvre mais malheureusement c'est pas une solution perenne à long terme.

    Si tu veux faire une saisie contrôlée, te faut
    1) utiliser fgets() car ça récupère tout ce que tape l'utilisateur
    2) analyser ce qui a été tapé avec sscanf() car cette fonction renvoie le nombre d'éléments correctement récupérés (et suffit de comparer ce nombre avec le nombre d'éléments attendus)

    Voici un exemple (tapé à capella sans compiler donc il risque d'y avoir une erreur ou deux mais c'est pour te montrer l'idée)

    Code c : 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
    #include<stdio.h>
     
    int saisie(char *prompt)
    {
        char chaine[81];
        int val;
     
        while (1)
        {
            printf("%s\n", prompt);
            fgets(chaine, 81, stdin);
     
           if (sscanf(saisie, "%d", &val) == 1)
               return val;
     
           printf("Erreur de saisie - Recommencez !\n");
       }
    }
     
    int main()
    {
        int a,b;
     
        a=saisie("Entrez le premier nombre");
        b=saisie("Entrez le second nombre");
     
        printf("%d+%d=%d\n",a,b,a+b);
    }
    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]

  4. #4
    Candidat au Club
    Inscrit en
    Octobre 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 3
    Par défaut
    Bonjour !

    D'abord, scanf() ne retourne pas un bool mais un int.
    je sais bien que la fonction scanf() ne retourne pas une valeur logique mais elle retourne 1 si l’entré est correcte ou 0 s’il y a un erreur lors de la saisie, mais n’oublie pas que 1 veut dire « true » et 0 : « false » ce qui veut dire que l’affectation de la valeur (que scanf retourne) pour une variable logique est bien possible.

    Donc la seule solution est de lire ce qu'a entré l'utilisateur et tester si cela correspond bien à un nombre entier inférieur à 32767 si vous êtes en 32 bits.
    Si le nombre entré est supérieur de la valeur maximale ou inferieur de la valeur minimale se passe Ce qu’on appelle en anglais « over flow » et le nombre ne sera même pas pris en mémoire, Donc ce que vous m’avez proposé n’est pas correcte.
    sache que l’utilisateur peut taper n’importe quoi ! (caractère, symbole, mots, phrase,…). Donc la meilleure solution ici est de suivre une méthode exacte qui prend en charge la vérification lors de la saisie, sachant que les entrés peuvent être différent de type «int » comme je disais.


    J’avais résolus cet exercice en C++ et voici son code :
    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
    #include<iostream>
    using namespace std;
    int main()
    {
        int x,y;
     
        cout<<"x=";
        cin>>x;
        while(cin.fail()) 
        {
           cin.clear();
           cin.sync();
           cout<<"Une erreur s'est produite ! \a"<<endl;
           cout<<"Valeur impossible !, Veuillez entrer une valeur entier  : "<<endl;
           cout<<"x=";
           cin>>x;
        }
        cin.sync();
     
        cout<<"y=";
        cin>>y;
        while(cin.fail()) 
        {
           cin.clear();
           cin.sync();
           cout<<"Une erreur s'est produite ! \a"<<endl;
           cout<<"Valeur impossible !, Veuillez entrer une valeur entier  : "<<endl;
           cout<<"y=";
           cin>>y;
        }
     
        cout<<x<<" + "<<y<<" = "<<x+y<<endl;
     
        system("pause");
        return 0;
    }
    S’il ya une erreur lors de la saisie nous devons effectuer deux ordres pour résoudre ce problème :
    • nettoyer le buffer des entrées incorrectes.

    • reprendre la situation de la fonction cin.fail() par défaut (cin.fail=false).

    Pour nettoyer le buffer on utilise la fonction cin.sync() et on utilise la fonction cin.clear() pour reprendre la situation initiale de la fonction cin.fail().
    Tout ce que je veux est :
    • comment nettoyer le buffer en C ?

    • comment ramener la fonction scanf à la situation initiale en C ?





    Mes salutations

  5. #5
    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
    raymond_prg
    je sais bien que la fonction scanf() ne retourne pas une valeur logique mais elle retourne 1 si l’entré est correcte ou 0 s’il y a un erreur lors de la saisie,...
    Non, ceci est inexact : scanf() retourne le nombre d'assignations réussies (0,1,2,...) ou EOF en cas d'erreur (ou fin de fichier) sur l'entrée avant toute tentative de conversion. Tester la valeur de retour permet de savoir si les conversions ont réussi.

    Ce qu’on appelle en anglais « over flow » et le nombre ne sera même pas pris en mémoire,
    La valeur obtenue ne sera pas égale au nombre entré évidemment, mais qui dit que la mémoire ne sera pas modifiée ?

    comment nettoyer le buffer en C ?
    En consultant la FAQ :Comment vider le buffer clavier ?

    comment ramener la fonction scanf à la situation initiale en C ?
    Qu'entends-tu par "situation initiale" ? Une fois le buffer vidé, on peut commencer une nouvelle lecture. Pour information , la fonction clearerr() permet d'effacer les indicateurs d'erreur et de fin de fichier sur le flux. Ces indicateurs sont testables via les fonctions ferror() et feof(). Ces indicateurs ne testent pas la validité de la chaine par rapport au format spécifié (validité qui est testée par la valeur de retour du scanf())

    Pierre Dolez
    Quel rapport entre un entier 32 bits et 32767 ? Avec un entier 16 bits, on comprendrait.

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par raymond_prg Voir le message
    je sais bien que la fonction scanf() ne retourne pas une valeur logique mais elle retourne 1 si l’entré est correcte ou 0 s’il y a un erreur lors de la saisie, mais n’oublie pas que 1 veut dire « true » et 0 : « false » ce qui veut dire que l’affectation de la valeur (que scanf retourne) pour une variable logique est bien possible.
    Non les fonctions Xscanf() retourne le nombre de conversions correctement effectuées (éventuellement 0 si la première n'a pas pu être faite) ou EOF. Avec ton code, EOF sera vu comme une lecture réussie.
    En outre, même si dans ton cas tu ne lis qu'une valeur et donc que, mis à part le EOF, la fonction ne renvoie que 0 ou 1, ce n'est pas généralisable.

    Pourquoi donc ne pas tester le retour de la fonction de la façon idiomatique qui n'a pas ces problèmes ?

    Citation Envoyé par raymond_prg Voir le message
    • comment nettoyer le buffer en C ?
    • comment ramener la fonction scanf à la situation initiale en C ?
    Il faut lire l'intégralité des caractères présents dans le flux d'entrée. Plusieurs solutions ont déjà été proposées sur le forum (cherche avec fclean ou fpurge, tu devrais trouver) et dans la FAQ.

  7. #7
    Invité
    Invité(e)
    Par défaut
    @diogene
    Pierre Dolez
    Quel rapport entre un entier 32 bits et 32767 ? Avec un entier 16 bits, on comprendrait.
    Naturellement, je voulais dire 16 bits. (je fais moins de fautes quand je code, pardon)
    Surprenant que raymond_prg ne l'ait pas vu. Sa leçon de programmation m'a bien intéressé.
    J'avoue que je n'ai pas lu son code C++, mais s'il a réussi à faire cet exercice en C++, avec un peu de patience il devrait y arriver assez facilement en C, d'autant qu'à part l'utilisation de io, le C++ n'apporte par grand-chose au C pour ce type d'opération très élémentaire. (je sais il y des fonctions comme clear() ou sync()).
    Si ça se trouve, l'intitulé de l'exercice est ce programme en C++ à transposer en C. Qu'en pensez-vous?

  8. #8
    Candidat au Club
    Inscrit en
    Octobre 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 3
    Par défaut
    slt, Je m'excuse pour le retard !

    Non, ceci est inexact : scanf() retourne le nombre d'assignations réussies (0,1,2,...)
    Vous avez raison mais je parlais du cas particulier de scanf() (avec un seul paramètre)

    ou EOF en cas d'erreur (ou fin de fichier) sur l'entrée avant toute tentative de conversion
    Qu’est-ce que le EOF !? pourriez – vous bien me l’expliquer ?

    mais qui dit que la mémoire ne sera pas modifiée ?
    Je n’ai pas dit que la mémoire sera modifiée !

    la fonction clearerr() permet d'effacer les indicateurs d'erreur et de fin de fichier sur le flux
    Qu'est-ce que le flux !? (je suis un débutant et je ne comprenais pas les réponses de la FAQ sur le flux).


    la fonction clearerr() permet d'effacer les indicateurs d'erreur et de fin de fichier sur le flux. Ces indicateurs sont testables via les fonctions ferror() et feof(). Ces indicateurs ne testent pas la validité de la chaine par rapport au format spécifié
    Svp, Je vous demande de me donner un exemple sur les fonctions clearerr, ferror et foef.

    Plusieurs solutions ont déjà été proposées sur le forum (cherche avec fclean ou fpurge, tu devrais trouver) et dans la FAQ.
    Svp, Je vous demande de me donner un exemple sur les fonctions fclean fpurge.

  9. #9
    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
    EOF est une constante particulière (definie par une macro #define, en fait un entier négatif) utilisée pour indiquer une fin de fichier, donc qu'il n'y a plus de valeurs à lire. Elle est parfois aussi utilisée pour indiquer un disfonctionnement sur un flux.

    Un flux est une entité utilisée pour concevoir logiquement les entrées-sorties d'une façon indépendante du périphérique utilisé. Il se présente comme une suite de bytes (représentant les données) à laquelle on associe certaines propriétés (flux d'entrée ou de sortie, flux texte ou binaire,...). On peut associer un flux à un fichier physique grace à fopen() et ensuite ce flux est contrôlé grace à la structure FILE créée par cette fonction. Il y a 3 flux texte ouverts en standard : FILE* stdin (connecté par défaut au clavier), FILE* stdout et FILE* stderr (connectés par défaut à la console).


    Pour fclean() ou fpurge(), le code est accessible via le lien que je t'ai déjà donné.

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par raymond_prg Voir le message
    Svp, Je vous demande de me donner un exemple sur les fonctions clearerr, ferror et foef.
    Code c : 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
    #include <stdio.h>
    int main()
    {
        int c;
        FILE *fp;
     
        fp=fopen("/etc/passwd", "r");
        while ((c=fgetc(fp)) != EOF) {
             printf("j'ai lu un caractère [%c]\n", c);
        }
     
        if (feof(fp)) {
             printf("Je ne peux plus rien lire parce que j'ai atteint la fin de fichier\n");
        }
        else {
             if (ferror(fp)){
                  printf("Je ne peux plus rien lire parce qu'il y a eu un problème lors de la lecture et que le fichier est maintenant inaccessible\n");
            }
            else {
                  printf("Je ne peux plus rien lire et je ne sais pas trop pourquoi mais le fichier est maintenant inaccessible\n");
            }
        }
        fclose(fp);
    }
    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]

  11. #11
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Bonsoir

    J'ai l'impresion qu'on s'est fort éloigné de la demande initiale

    Citation Envoyé par raymond_prg
    Je cherche de l’aide pour :
    Écrire un programme qui fait la somme de deux nombres de types (int) et vérifie d’abord qu’ils sont de même type (int).
    La maniere la plus triviale est d'utiliser des gets() et des atoi()

    On peut fignoler en analysant le contenu des chaine rendues par gets() avant d'effectuer les atoi()

  12. #12
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Citation Envoyé par olibara Voir le message
    La maniere la plus triviale est d'utiliser des gets() et des atoi()

    On peut fignoler en analysant le contenu des chaine rendues par gets() avant d'effectuer les atoi()
    Tu voulais très certainement dire fgets() et non gets(), strtol() et non atoi().

  13. #13
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Tu voulais très certainement dire fgets() et non gets(), strtol() et non atoi().
    Ben non je voulais bien dire gets() : il n'a pas été spécifié que l'input etait un fichier il semble au contraire qu'il s'agit d'un input clavier, mais il pourrait effectivement faire un fgets sur le stdin

    Et je voulais aussi dire atoi() dans le cadre de la proposition élémentaire

    Pourquoi considere tu qu'il faut absolument faire des fgets() et des strtol() ??

  14. #14
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    gets est une fonction dangereuse, qu'il faut bannir, car elle présente une grosse faille de sécurité. En effet, vu qu'on ne lui indique pas la quantité maximale de données à écrire dans le buffer, elle est susceptible d'occasionner un débordement de tampon (ce qui provoque un crash dans le moins pire des cas) et laisse donc à un utilisateur suffisamment malin (un mec qui s'y connait, quand même) la possibilité d'exécuter du code arbitraire.
    Cette fonction doit toujours être remplacée par fgets.

    atoi présente aussi des problèmes de sécurité.
    The atoi() function is not thread-safe and also not async-cancel safe.

    The atoi() function has been deprecated by strtol() and should not be used in new code.

  15. #15
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Je n'ai pas relu dernièrement la question d'origine, mais de mémoire, il s'agissait de lire quelque-chose et avant de faire l'addition de VERIFIER qu'il s'agit bien d'un entier. J'ai essayé de tendre la perche à notre ami Raymond, mais malheureusement il ne l'a pas très bien pris.
    Donc, à mon avis le professeur attend une lecture de caractères et la "formation" du nombre entier.
    Dans tous les cas, il s'agit d'un exercice, et tant qu'on ne connait pas le sujet du chapitre actuellement étudié, il y a, à mon avis, fort peu de chances de tomber juste.

  16. #16
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Citation Envoyé par olibara Voir le message
    Pourquoi considere tu qu'il faut absolument faire des fgets() et des strtol() ??
    jeroman viens de résumer mes pensées je rajouterais juste qu'en plus atoi() ne détecte pas les erreurs.

Discussions similaires

  1. Entrée dans un While
    Par Deallyra dans le forum Débuter
    Réponses: 7
    Dernier message: 24/11/2008, 20h14
  2. Verif Enreg entre 2 tables
    Par jackyhilary dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 14/01/2008, 18h03
  3. [MySQL] gestion d'affichage entre deux boucle while mysql_fetch_array()
    Par tkwleboss dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 29/11/2007, 21h37
  4. [MySQL] conflit entre deux fonction while
    Par guillaumeIOB dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 04/12/2006, 12h56
  5. [MySQL] Conflit entre deux fonction WHILE
    Par guillaumeIOB dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 28/11/2006, 18h15

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