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 :

Vérifier si le stdin est vide . . .


Sujet :

C

  1. #1
    Invité1
    Invité(e)
    Par défaut Vérifier si le stdin est vide . . .
    Tout est dans le titre . . . J'ai une fonction comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void PurgeStdin(void){
    	int c;
     
    	c = getchar();
     
    	while(c != EOF && c != '\n'){
    		c = getchar();
    	}
    }
    qui vide le buffer de stdin . . . Le problème est que par exemple, je veut qu'il soit vidé si l'utilisateur entre quelque chose de trop grand pour l'espace que j'ai alloué, mais si il a entré quelque chose de mauvais qui est pas trop grand, il ne doit pas le vider parce que ma fonction va faire un getchar() et comme stdin est vide, le programme attend qu'on appuie sur enter . . .

    C'est peut-être pas clair, mais c'est ça

    Merci beaucoup!

    Alex

  2. #2
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Donne un exemple de code (compilable) qui produit le problème.

  3. #3
    Invité1
    Invité(e)
    Par défaut
    c'est pas vraiment un problème . . . je veut seulement savoir comment vérifier si stdin est vide avant de le vider (si il est vide, on le vide pas . . .)

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Tu ne peux.
    Tu ne dois vider que si une fonction te dit qu'elle n'a pas tout lu.

    Dans le cas de fgets() par exemple, c'est quand le buffer ne contient pas de \n...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Alexandreg12 Voir le message
    c'est pas vraiment un problème . . . je veut seulement savoir comment vérifier si stdin est vide avant de le vider (si il est vide, on le vide pas . . .)
    Le principe, c'est de vider immédiatement après avoir utilisé une fonction de saisie et non avant, car on ne sait pas ce qui s'est passé avant...

    Si tu utilises systématiquement la séquence

    fgets()
    fclean() /* non standard */

    ou une seule fonction regroupant les deux, pour faire tes saisies, tu n'as plus jamais de problèmes de saisies.

    Le code de fclean() a été maintes fois publié sur ce forum.

    La chaine saisie peut ensuite être traitée

    - comme une chaine
    - comme une valeur numérique (strtol() etc.)
    - comme un caractère (chaine[0] etc).

  6. #6
    Invité1
    Invité(e)
    Par défaut
    J'ai trouvé une solution en utilisant strlen pour savoir si l'entrée était trop grande, merci!

    Alex

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Alexandreg12 Voir le message
    J'ai trouvé une solution en utilisant strlen pour savoir si l'entrée était trop grande, merci!
    Ca fout la trouille... Montre ton code.

    Qu'est-ce qui ne va pas avec fgets() ?

  8. #8
    Invité1
    Invité(e)
    Par défaut
    il n'y a rien qui vas pas avec fgets . . . ce qui a c'est que si ce que j'ai entré est pas dans mes if, else if, il y a un else qui dit que ce n'est pas une bonne entrée et qui recommence la boucle qui permet d'entrer une string.

    Si l'entrée n'étais pas trop grande, tout va bien, mais si la mauvaise entrée était plus grande que 32bytes, il faut vider le stdin. Mais il faut pas le vider si ce qui était entré était plus petit que 32 parce que la fonction qui le vide utilise getchar() et donc va interrompre le programme.

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Alexandreg12 Voir le message
    il n'y a rien qui vas pas avec fgets . . . ce qui a c'est que si ce que j'ai entré est pas dans mes if, else if, il y a un else qui dit que ce n'est pas une bonne entrée et qui recommence la boucle qui permet d'entrer une string.

    Si l'entrée n'étais pas trop grande, tout va bien, mais si la mauvaise entrée était plus grande que 32bytes, il faut vider le stdin. Mais il faut pas le vider si ce qui était entré était plus petit que 32 parce que la fonction qui le vide utilise getchar() et donc va interrompre le programme.
    Montre ton code, je le sens mal...

    Tu as trouvé le code de fclean() ?

    Ici, il y a 'nettoyer()' :

    http://www.developpez.net/forums/m3414790-28/

    etc.

  10. #10
    Invité1
    Invité(e)
    Par défaut
    oui j'ai trouvé le fclean()

    J'explique:

    J'ai un char *Cmd;.

    Ensuite, un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            Cmd = (char *)malloc(32);
    	if(Cmd==NULL){
    		puts("Memory allocation error for Cmd (32 bytes - char)");
    		puts("Ending the program...");
    		return 0;
    	}
    mon fgets: Permet d'entrer 32 bytes d'info! et est dans une boucle.

    J'ai des if,else qui regardent ce qui a été écrit.

    Le dernier else (ce qui est écrit, pas reconnu), dit que ce qui est écrit n'est pas reconnu, et la boucle recommence . . . Par contre! si et seulement SI l'entrée était plus grande que 32 bytes, il faut vider le stdin.

    Si on le vide alors que l'entrée n'étaient pas trop grande, la fonction va interrompre le programme puisqu'elle utilise getchar() et que le stdin est déjà vide! . . .


    Je commence tout juste à programmer alors ne soyez pas trop dur! Si vous avec une meilleure solution, n'hésitez pas


    Alex

  11. #11
    Invité1
    Invité(e)
    Par défaut
    Comme j'ai dit, je commence tout juste en c! (en programmation en fait)

    Il ne faut pas être étonné si je ne fais pas le code le plus propre du monde! L'important c'est qu'il soit "sécuritaire" . . .

    Le reste, ça viendra avec l'expérience!

    En plus, c'est uniquement un passe-temps!

    Alex

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Alexandreg12 Voir le message
    oui j'ai trouvé le fclean()

    J'explique:

    J'ai un char *Cmd;.

    Ensuite, un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            Cmd = (char *)malloc(32);
    	if(Cmd==NULL){
    		puts("Memory allocation error for Cmd (32 bytes - char)");
    		puts("Ending the program...");
    		return 0;
    	}
    A quoi ça sert d'allouer une taille fixe ?

    Est-t-il utile de faire plus compliqué que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       char Cmd[32];
       fgets(Cmd, sizeof Cmd, stdin);
    ?
    Permet d'entrer 32 bytes d'info! et est dans une boucle.
    31 avec le '\n' 30 sans le '\n' .

    J'ai des if,else qui regardent ce qui a été écrit.
    Le dernier else (ce qui est écrit, pas reconnu), dit que ce qui est écrit n'est pas reconnu, et la boucle recommence . . . Par contre! si et seulement SI l'entrée était plus grande que 32 bytes, il faut vider le stdin.
    On se tue à te dire que c'est le rôle de fclean() qu'il faut placer immédiatement et systématiquement après le fgets() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       char Cmd[32];
       fgets(Cmd, sizeof Cmd, stdin);
       fclean(Cmd, stdin);
     
       /* suite des traitements, tests etc. */
    Faut pas aller chercher des trucs tordus. La complexité maitrisée est une somme d'éléments simples.

  13. #13
    Invité1
    Invité(e)
    Par défaut
    effectivement, un simple array pourrait le faire! J'étais juste dans l'apprentissage des pointeurs et je m'étais dit que je pouvais faire un free() après quand j'en avait plus besoin

    Pour ce fichu fclean() . . . Pouvez, vous me donner un mini-exemple du code de fclean()?

    Merci beaucoup de votre patience

    Alex

  14. #14
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Alexandreg12 Voir le message
    Pour ce fichu fclean() . . . Pouvez, vous me donner un mini-exemple du code de fclean()?
    oui j'ai trouvé le fclean()
    On m'aurait menti à l'insu de mon plein gré ?

  15. #15
    Invité1
    Invité(e)
    Par défaut
    non, je croyais avoir trouvé, mais honnêtement j'arrive pas trop à comprendre et je me demandes si j'ai trouvé la bonne fonction . . . (je suis presque certain que je ne comprend juste pas trop ce qu'elle fait . . .)

    un code commenté serait bien . . .

  16. #16
    Invité1
    Invité(e)
    Par défaut
    chercher '\n' dans la chaine
    Si on l'a trouvé
    l'éliminer
    sinon
    lire les caractères non lus jusqu'au '\n'.

    C'est de vous

    En fait, ce que j'ai fait est très semblable . . . Seulement long pour rien, je vais essayer d'optimiser!

    Merci beaucoup!

  17. #17
    Invité1
    Invité(e)
    Par défaut
    Ce que je faisait, c'est que je vérifiais si l'entrée occupait tout le buffer . . .

    Si elle l'occupait entièrement, je cherchait pour le \n et si il n'était pas trouvé (l'entrée est plus longue que le buffer), on purge le stdin . . .si on trouve \n, l'entrée était juste de la bonne grandeur alors pas besoin de purger le stdin . . .

    pour l'utilisation que j'en fait, cela me suffisait . . .

    Mais merci de vos conseils et de votre patience!

    Je vais essayer de faire mieux!

    Alex

  18. #18
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Alexandreg12 Voir le message
    non, je croyais avoir trouvé
    Et le lien que j'ai indiqué ici ? :

    http://www.developpez.net/forums/m3587632-9/

  19. #19
    Invité1
    Invité(e)
    Par défaut
    J'ai fini par comprendre Je vais arranger mon code pour le rendre plus petit, mais en gros, il faisait la même chose . . .


    Merci beaucoup!

    Alex

Discussions similaires

  1. Vérifier si unPictureBox.Image est vide
    Par DarkSeiryu dans le forum Windows Forms
    Réponses: 2
    Dernier message: 16/01/2009, 10h09
  2. Vérifier qu'un dossier est vide
    Par coincoin22 dans le forum Shell et commandes GNU
    Réponses: 7
    Dernier message: 26/07/2007, 16h58
  3. vérifier qu'un champ est vide dans un formulaire
    Par dr_feelgood dans le forum IHM
    Réponses: 3
    Dernier message: 08/06/2007, 07h21
  4. Réponses: 2
    Dernier message: 21/02/2007, 10h27
  5. [Tableaux] Vérifier si un champ est vide !
    Par Tr@nkill dans le forum Langage
    Réponses: 9
    Dernier message: 16/05/2006, 16h11

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