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 de saisie


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2019
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ariège (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2019
    Messages : 11
    Par défaut verification de saisie
    Bonjour!

    J'essaye de vérifier la saisie utilisateur en ne prenant que des entiers. A votre avis, que se passe t-il en matière de mémoire et de rapidité?
    Pour le compiler j'ai utiliser l'option -Wall et j'ai un warning à cause de l'expression régulier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf(" %[01]",&valid);
    Je n'ai pas non plus pu ecrire:
    Comment ça se fait?

    Et voici mon 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
    while(valid!=49){
    		while(verifNb!=1){
    			puts("\nEcrivez un entier\n");
    			verifNb = scanf(" %3d",&nb);
    			viderBuffer();
    			}
    		verifNb=0;
    		printf("Avez-vous bien ecrit: %d\n",nb);
    		while(valid!=49 && verifValid !=1){
    			puts("Taper 0 pour non ou 1 pour valider\n");
    			verifValid = scanf(" %[01]",&valid);
    			viderBuffer();
    			}
    		verifValid=0;
    	}
    	printf("%d est valide\n",nb);
    Merci par avance pour vos conseils!

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2019
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ariège (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2019
    Messages : 11
    Par défaut
    Citation Envoyé par foetus Voir le message
    Je suis désolé, j'avais déjà vu ce genre de texte et je ne le comprends pas.
    Pourquoi scanf(" %[01]",&valid); genere un warning?

    Citation Envoyé par Sve@r Voir le message
    Bonjour [...]
    .
    Dans mon cas il s'agit de récupérer des entiers saisis au clavier, de taille max imposés et de rejeter tout le reste. Je ne comprends pas pourquoi tu me conseilles autre chose que scanf.
    Pour ce qui est de vider le buffer toutes les trois minutes, je croyais bien faire en renettoyant après chaque utilisation de scanf. ( et non je n'ai pas fflush(stdin)...)

    quand est-il des trois while, est-ce tres gourmand en ressources?

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par philippppe Voir le message
    Pourquoi scanf(" %[01]",&valid); genere un warning?
    Peut-être parce que le caractère "%" implique un format indiquant à la fonction le type qu'elle devra récupérer (%d=int, %f=float, etc...) et que toi tu n'en mets pas...

    Citation Envoyé par philippppe Voir le message
    Dans mon cas il s'agit de récupérer des entiers saisis au clavier, de taille max imposés et de rejeter tout le reste. Je ne comprends pas pourquoi tu me conseilles autre chose que scanf.
    Parce que scanf (scan formaté) implique un truc "formaté" et que ce que tape l'utilisateur est tout sauf formaté. Rien que le <return> qu'il doit taper pour valider son int fout déjà la dawa dans le code car il n'est pas traité par "%d" et reste donc à faire chier la saisie suivante (et bonjour la migraine si la saisie de ce fameux int a lieu dans une alternative => un coup elle y est un coup elle n'y est pas !!!). D'où mon fgets() initial pour vider tout stdin tout en le récupérant pour le traiter plus tard.

    Citation Envoyé par philippppe Voir le message
    Pour ce qui est de vider le buffer toutes les trois minutes, je croyais bien faire en renettoyant après chaque utilisation de scanf.
    "je croyais", "renettoyer" tout est là. Comme je l'ai dit, celui qui gère ses IO sait en permanence ce que contient son buffer et n'a donc pas besoin de "renettoyer" quoi que ce soit. Si tu écris int a=0, tu sais ce que contient "a". Tu ne vas pas réécrire a=0 toutes les 15 lignes en croyant bien faire...


    Citation Envoyé par philippppe Voir le message
    qu'en est-il des trois while, est-ce tres gourmand en ressources?
    Pas spécialement (il y a pas de calcul compliqué, pas de tableaux à déplacer). Mais bon ce n'est pas non plus le summum de la programmation. Déjà tu as deux variables différentes (verifNb et verifValid) pour faire la même chose à deux moments différents (une variable suffit donc). Plus tu testes deux fois valid != 49 (pourquoi 49 d'ailleurs?) et tu affectes ta variable verifNb sans la traiter. Ce n'est pas grand chose mais c'est toujours plus gourmand que si tu ne le faisais pas.
    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]

  5. #5
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    Citation Envoyé par philippppe Voir le message
    Je suis désolé, j'avais déjà vu ce genre de texte et je ne le comprends pas.
    Pourquoi scanf(" %[01]",&valid); genere un warning?
    Arrête de faire le toto le format est %[flags][width][.precision][length]specifier
    • Il est où le specifier (spécificateur en français apparemment) ?
    • Les crochets ne sont pas autorisés : c'est pour dire que le champs est facultatif "The format specifier can also contain sub-specifiers: flags, width, .precision and modifiers (in that order), which are optional"

  6. #6
    Membre habitué
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2019
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ariège (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2019
    Messages : 11
    Par défaut
    merci pour vos agreables reponses d'êtres supérieurs... toute mes excuses d'avoir posté une question de debutants sur un forum d'expert.
    Je quitte ce site plein de compréhension et de bienveillance. bravo les gars

  7. #7
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    merci pour ton agréable question "Pourquoi scanf(" %[01]",&valid); genere un warning?" posée 2 fois... toute mes excuses d'avoir répondu à une question de débutants alors qu'il n'y a qu'à lire la documentation [en anglais certes].
    Je te remercie pour ta gentillesse "ce site plein de compréhension et de bienveillance". bravo O.P. (<- original poster)


    Édit : Voici le warning
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    main.c:15:15: warning: format ‘%[01’ expects argument of type ‘char *’, but argument 2 has type ‘int *’ [-Wformat=]
       15 |     scanf("%[01]",&valid);
          |            ~~~^   ~~~~~~
          |               |   |
          |               |   int *
          |               char *
          |            %l[
    J'en conclus que tu ne sais pas lire l'anglais. Ton format ne passe pas et toi, au lieu de regarder la documentation, tu viens poster

  8. #8
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 256
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 256
    Par défaut
    j'ai un warning à cause de l'expression régulier
    Je ne savais pas que scanf gérait les expressions régulières (je suis pas programmeur), mais encore faut il les présenter correctement (pas de % devant).
    C'est bien indiqué dans la doc.

    Il restera un petit bémol à cette façon de faire: si l'entrée est plus grande que 1024 il restera des trucs sans stdin.
    Sauf que dans le cas de figure ici présent, l'entrée est sensée être un entier. Si tu dois traiter un entier de 1024 caractères ...... Je pense que tu as été plus que large.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par philippppe Voir le message
    Merci par avance pour vos conseils!
    Mon premier conseil est qu'il n'est jamais nécessaire de vider le buffer (ta fonction videBuffer() que tu appelles toutes les 3 mn). Déjà parce que celui qui gère bien ses IO ne se retrouve jamais avec un buffer contenant des trucs qu'il n'est pas censé contenir. Et surtout parce qu'un buffer ce n'est pas forcément le clavier. Si par exemple tu es dans le monde Unix, un programme peut recevoir ses données depuis un autre programme via un pipe et dans ce cas le buffer c'est la sortie de l'autre programme => si tu le vides inconsidérément tu perds les données de l'autre programme. Accessoirement j'espère que cette fonction videBuffer() ne travaille pas à coup de fflush(stdin)...

    Sinon moi quand je veux "sécuriser" mes saisies je passe par fgets() + sscanf(). Le fgets() c'est pour récupérer le contenu de mon clavier sans me préoccuper de sa nature et le sscanf() c'est pour extraire le nombre se trouvant dans le contenu extrait.
    Exemple
    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
    int saisieInt(char *prompt) {
    	char tampon[1024 + 1];
    	int nb;
     
    	while (1) {
    		fputs(prompt, stdout);
    		fflush(stdout);
    		fgets(tampon,1024 + 1, stdin);
    		if (sscanf(tampon, "%d", &nb) > 0) break;
    		printf("Saisie incorrecte, recommencez !!!\n");
    	}
    	return nb;
    }
     
    int main() {
    	int nb=saisieInt("Votre nombre ?");
    	printf("nb=%d\n", nb);
    }
    Il restera un petit bémol à cette façon de faire: si l'entrée est plus grande que 1024 il restera des trucs sans stdin. Dans la majorité des cas cette probabilité peut être négligée (ratio "danger/coût de codage") d'autant plus que la valeur 1024 peut être mise en macro ce qui permet de recalibrer facilement le code si nécessaire. Et si vraiment c'est problématique alors on peut remplacer fgets() par getline() qui, elle, récupère toute une ligne quelle que soit sa taille (mais fatalement elle est plus lourde).
    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]

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Et c'est censé vouloir dire quoi %[01] comme pattern ?
    Parce que vu que c'est absolument pas permis comme syntaxe, faudrait peut-être commencer par savoir ce que tu espères faire.

    Récupérer seulement 0 ou 1 ? %1d et tu vérifies que c'est correct.
    Mais dans un cas aussi trivial, autant récupérer la string entière, et donc éviter tous les maux de tête de buffer pas entièrement vidé et autre, et vérifier '0' ou '1'.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

Discussions similaires

  1. verification champ saisi formulaire
    Par calitom dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 10/01/2008, 14h36
  2. verification de saisie
    Par daff86 dans le forum Tkinter
    Réponses: 2
    Dernier message: 30/05/2007, 16h02
  3. Verification de saisie
    Par abigaelle dans le forum Général Python
    Réponses: 8
    Dernier message: 03/05/2006, 14h11
  4. Verification de saisie dans un sous-formulaire
    Par OBIWAN64 dans le forum Access
    Réponses: 4
    Dernier message: 15/03/2006, 12h18

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