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 :

Comment vider stdin sans connaitre le dernier caractère qu'il contient ?


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Points : 70
    Points
    70
    Par défaut Comment vider stdin sans connaitre le dernier caractère qu'il contient ?
    Bonjour,

    Ma question est dans le titre de la discussion.

    J'ai cherché du côté de méthodes permettant de connaître le nombre de caractères restant dans stdin, mais sans résultat..

    NB : Il faut donc bannir toute solution consistant à vider tant que '\n' n'est pas lu.

    Si vous avez une solution ou une piste, ça m'aiderait pas mal.

    Merci

    Edit :
    La seule solution que j'ai actuellement trouvé(non portable) est de simuler l'appui d'un caractère de terminaison et de faire un _getch() tant que le caractère de terminaison n'est pas rencontré..
    Ou encore la simulation d'une chaîne de caractère de terminaison. Mais ce sont des solutions approximatives et pouvant être sujettes à des erreurs.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 378
    Points : 23 674
    Points
    23 674
    Par défaut
    Le problème vient du fait que stdin est « l'entrée standard » et que tu ne connais pas la nature de celle-ci à l'avance : tu ne peux pas savoir si ce que tu lis provient d'un fichier, d'un tube, d'un socket ou du clavier. Ça signifie que, dans ce dernier cas, tu ne peux pas savoir à l'avance si l'utilisateur a réellement fini d'entrer ses informations ou s'il va en ajouter d'autres quelques secondes plus tard.

    Si ce que tu veux faire, par contre, c'est vider le buffer clavier à un moment donné et ne prendre en considération que ceux qui arriveront après (pour faire une saisie fiable), alors il faut passer en mode non-bloquant et lire les caractères jusqu'à ce que le tampon soit vide et que l'appel « échoue ». C'est possible mais c'est de la programmation système et ça ne fait pas partie de la norme C.

    On en parlait ici.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Points : 70
    Points
    70
    Par défaut
    Merci pour ta réponse. Je vais regarder de ce côté là

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 677
    Points
    13 677
    Billets dans le blog
    1
    Par défaut
    @Obsidian : ne serait-il pas temps de mettre à jour la FAQ à ce sujet ?

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Points : 70
    Points
    70
    Par défaut
    Edit :
    La seule solution que j'ai actuellement trouvé(non portable) est de simuler l'appui d'un caractère de terminaison et de faire un _getch() tant que le caractère de terminaison n'est pas rencontré..
    Ou encore la simulation d'une chaîne de caractère de terminaison. Mais ce sont des solutions approximatives et pouvant être sujettes à des erreurs.
    Petite question. Ma solution est-elle valable d'après vous ?

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 192
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 192
    Points : 17 154
    Points
    17 154
    Par défaut
    en effet, ce n'est pas une bonne situation, rien ne dit que tu parviennent à écrire au fond de stdin. surtout si c'est une socket, un fichier en lecture seule ou /dev/random
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par leternel Voir le message
    en effet, ce n'est pas une bonne situation, rien ne dit que tu parviennent à écrire au fond de stdin. surtout si c'est une socket, un fichier en lecture seule ou /dev/random
    Merci Du même avis.

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 378
    Points : 23 674
    Points
    23 674
    Par défaut
    Citation Envoyé par Bktero Voir le message
    @Obsidian : ne serait-il pas temps de mettre à jour la FAQ à ce sujet ?
    Si, probablement, mais le sujet a l'air de diviser les opinions et je ne suis pas personnellement en charge de la FAQ. Il faudrait en parler aux personnes concernées.

  9. #9
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    un truc comme ça?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int   ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 378
    Points : 23 674
    Points
    23 674
    Par défaut
    Citation Envoyé par jabbounet Voir le message
    un truc comme ça?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int   ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
    Non, parce que ce n'est valable que sur un fichier. Si l'entrée standard est le clavier, par exemple, ta boucle bloquera. Et selon la discipline appliquée au terminal, taper une touche peut ne pas suffire à la débloquer : les caractères s'accumuleront du côté utilisateur jusqu'à ce qu'il appuie sur Return.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 376
    Points : 41 544
    Points
    41 544
    Par défaut
    Je n'ai pas bien compris le but de la manœuvre. S'agit-il de faire des entrées non-bloquantes?
    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.

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 378
    Points : 23 674
    Points
    23 674
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Je n'ai pas bien compris le but de la manœuvre. S'agit-il de faire des entrées non-bloquantes?
    Oui. Mais faire cela relève de la programmation système et pas du C standard, malheureusement.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 376
    Points : 41 544
    Points
    41 544
    Par défaut
    Oui, et dans ce cas, j'irais directement sur **curses, avec kbhit() et getch().
    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.

  14. #14
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 378
    Points : 23 674
    Points
    23 674
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Oui, et dans ce cas, j'irais directement sur **curses, avec kbhit() et getch().
    C'est vrai mais c'est toujours la même chose : ce n'est pas une manière fiable de vider le buffer d'entrée quelque soit ce qu'il contient.

  15. #15
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    ou alors un bon vieux read.
    man read:
    Name
    read - read from a file descriptor
    Synopsis

    #include <unistd.h>
    ssize_t read(int fd, void *buf, size_t count);

    Description

    read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.

    On files that support seeking, the read operation commences at the current file offset, and the file offset is incremented by the number of bytes read. If the current file offset is at or past the end of file, no bytes are read, and read() returns zero.

    If count is zero, read() may detect the errors described below. In the absence of any errors, or if read() does not check for errors, a read() with a count of 0 returns zero and has no other effects.

    If count is greater than SSIZE_MAX, the result is unspecified.

    Return Value
    On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par jabbounet Voir le message
    ou alors un bon vieux read.
    Si count dépasse le nombre de caractères dans stdin, read attend l'ajout de nouveau caractères.

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

Discussions similaires

  1. Vider STDIN sans attente d'une action
    Par cerede2000 dans le forum C
    Réponses: 10
    Dernier message: 16/11/2008, 16h02
  2. Réponses: 2
    Dernier message: 10/10/2007, 12h45
  3. Comment allouer de la memoire sans connaitre la taille
    Par mIch°° dans le forum Delphi
    Réponses: 2
    Dernier message: 16/01/2007, 09h25
  4. Comment ouvrir un fichier sans connaitre son nom
    Par APoLLoN1234 dans le forum C++
    Réponses: 8
    Dernier message: 10/09/2006, 18h04
  5. comment vider une chaine de caractère
    Par gaut dans le forum C
    Réponses: 13
    Dernier message: 12/09/2003, 11h30

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