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 :

Lecture entree standard


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2005
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 110
    Par défaut Lecture entree standard
    Bonjour,

    j'ai cherche sur le forum et j'ai trouve qqs solutions a mon probleme. En fait, j'aimerai lire au clavier dans une boucle. Le probleme est toujours le meme, le buffer ne se vide pas.
    fflush() est a deconseille, fpurge() connais pas... mais ca doit pas etre mieux?
    Et vider le buffer a coup de fgets() c'est franchement laid
    Voici mon bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    while (1) {
         printf("Nom : "); fgets(nom, 19, stdin); nom[strlen(nom)-1] = '\0';
         printf("Age : "); age = atoi(fgets(a, 3, stdin));
         sprintf(requete, "insert into t1 values (\'%s\', %d)", nom, age);
         printf("req:%s\n", requete);
         if (sqlite3_exec(sql, requete, 0, 0, 0) > 0) {
            perror("Erreur d'insertion\n");
            exit(4);
        }
    }

  2. #2
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    fflush() est a deconseille
    Pourquoi?
    est fait pour purger le buffer d'entrée, c'est la commande de forçage.
    Elle est "ANSI C".

  3. #3
    Membre confirmé
    Inscrit en
    Novembre 2005
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 110
    Par défaut
    C'est ce que j'ai entendu en tout cas...
    Je vais faire comme ca alors

  4. #4
    Membre émérite
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Par défaut
    Citation Envoyé par seriousme
    Pourquoi?
    est fait pour purger le buffer d'entrée, c'est la commande de forçage.
    Elle est "ANSI C".
    Vraiment n'importe quoi.
    fflush est effectivement standard. Par contre, la norme ne défini son comportement QUE pour un flux sortant..

    Donc le comportement d'un fflush(stdin) est complètement indéfini....
    A ne pas utiliser, donc.
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  5. #5
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par Pouic
    Donc le comportement d'un fflush(stdin) est complètement indéfini....
    Pas sous Windows, bon apres c'est sur c'est pas portable.

    Recherche sur le forum il y a une fonction clean qui traine pour apres fgets.

  6. #6
    Membre confirmé
    Inscrit en
    Novembre 2005
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 110
    Par défaut
    Ah oui en effet... je vais donc utiliser fpurge(stdin)

  7. #7
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    qui n'est pas standard non plus..

    La solution c'est de vider le buffer avec des fgetc ou des fgets

  8. #8
    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 seriousme
    Pourquoi?
    est fait pour purger le buffer d'entrée, c'est la commande de forçage.
    Elle est "ANSI C".
    Merci d'arréter de dire des bêtises.

    Le comportement de fflush() n'est défini par la norme que pour les flux sortants.

    Le comportement de fflush(stdin) est parfois défini sur certaines implémentations, mais ce n'est pas portable.

  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 mrttlemonde
    j'ai cherche sur le forum et j'ai trouve qqs solutions a mon probleme. En fait, j'aimerai lire au clavier dans une boucle. Le probleme est toujours le meme, le buffer ne se vide pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    while (1) {
         printf("Nom : "); fgets(nom, 19, stdin); nom[strlen(nom)-1] = '\0';
         printf("Age : "); age = atoi(fgets(a, 3, stdin));
         sprintf(requete, "insert into t1 values (\'%s\', %d)", nom, age);
         printf("req:%s\n", requete);
         if (sqlite3_exec(sql, requete, 0, 0, 0) > 0) {
            perror("Erreur d'insertion\n");
            exit(4);
        }
    }
    Si tu veux utiliser fgets() comme un 'limiteur de taille saisie', tu es automatiquement confronté au problème du flux stdin incomplètement vidé. La stratégie
    • je salis
    • je nettoie
    est donc plus que jamais d'actualité.
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    /* nettoyeur */
    static void clean (char *s, FILE *fp)
    {
       /* search ... */
       char *p = strchr (s, '\n'); /* <string.h> */
       if (p != NULL)
       {
          /* ... and kill */
          *p = 0;
       }
       else
       {
          /* purge */
          int c;
          while ((c = fgetc(fp)) != '\n' && c != EOF)
          {
          }
       }
    }
     
    int main (void)
    {
    #define LEN_NAME 18
    #define LEN_AGE 3
       int end = 0;
     
       while (!end)
       {
          char nom[LEN_NAME + 2];
          int age;
     
          printf("Nom (or ""<enter> to quit) : ");
          fflush (stdout);
          fgets(nom, LEN_NAME + 1, stdin);
          clean(nom, stdin);
     
          end = *nom == 0;
          if (end)
          {
             /* premiere fois de ma vie que j'utilise cet engin... */
             continue;
          }
     
          {
             char *pend;
             do
             {
                char a[LEN_AGE + 2];
                printf("Age : ");
                fflush (stdout);
                fgets(a, LEN_AGE + 1, stdin);
                clean(a, stdin);
                age = (int) strtol(a, &pend, 10);
             }
             while (*pend != 0);
          }
     
          {
             char requete[128];
             sprintf(requete, "insert into t1 values (\'%s\', %d)", nom, age);
             printf("req:%s\n", requete);
             /* ... */
          }
       }
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Nom (or <enter> to quit) : azertyuiopqsdfghjklmwxcvbn
    Age : a
    Age : a1
    Age : 1a
    Age : 11a
    Age : 111a
    req:insert into t1 values ('azertyuiopqsdfghjk', 111)
    Nom (or <enter> to quit) :
     
    Press ENTER to continue.

  10. #10
    Membre confirmé
    Inscrit en
    Novembre 2005
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 110
    Par défaut
    Oui mais c'est qd meme pas tres pratique non? L'utilisateur va devoir vider sois meme le buffer alors? a coups de fgets c'est special.
    Faut dire que j'avais jamais cherche de solution a cela. C'est vrai que j'utilisais fflush(stdin) et que ca fonctionnait tres bien (et tjs mnt) mais si ce n'est pas portable, vaut mieux essayer autre chose

  11. #11
    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 mrttlemonde
    Oui mais c'est qd meme pas tres pratique non? L'utilisateur va devoir vider sois meme le buffer alors? a coups de fgets c'est special.
    Faut dire que j'avais jamais cherche de solution a cela. C'est vrai que j'utilisais fflush(stdin) et que ca fonctionnait tres bien (et tjs mnt) mais si ce n'est pas portable, vaut mieux essayer autre chose
    Il est évident que dans l'industrie on écrit une fonction qui fait tout bien comme il faut comme get_line() :

    http://emmanuel-delahaye.developpez.com/clib.htm
    Modules IO + FSTR

  12. #12
    Membre confirmé
    Inscrit en
    Novembre 2005
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 110
    Par défaut
    Je vais essayer votre methode :-)
    Ca donnera surrement bien

Discussions similaires

  1. Réponses: 2
    Dernier message: 16/07/2007, 08h00
  2. [débutant] lecture entree clavier
    Par bendamen dans le forum Langage
    Réponses: 2
    Dernier message: 07/05/2007, 09h24
  3. comment lire les arguments sur l'entree standard
    Par batotoba dans le forum ANT
    Réponses: 1
    Dernier message: 04/09/2006, 17h50
  4. Processus en background et entrée standard
    Par kennn13 dans le forum Linux
    Réponses: 1
    Dernier message: 26/01/2006, 17h31
  5. Awk - interpréter l'entrée standard
    Par narmataru dans le forum Linux
    Réponses: 7
    Dernier message: 26/01/2005, 10h40

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