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 :

saisie getline string


Sujet :

C++

  1. #1
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut saisie getline string
    Bonjour,

    la fonction getline est zappée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream>
    #include <string>
    #include "entrees.hpp"
     
    int main(){
      int choix;
      while( ! saisir_int(choix,"entrez un nombre: "))
        ;
      std::string X;
      saisir_string(X,"entrez une chaine");
      std::cout<<X<<std::endl;
    }
    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
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <limits>
     
    void vider_buffer();
     
    void saisir_string(std::string &variable, const std::string &message){
      while(true){
        std::cout << message;
        std::getline(std::cin, variable); 
        if(std::cin.bad() || std::cin.eof()){
          std::cerr << "Erreur, saisie incorrecte." << std::endl;
          if(std::cin.eof()){
    	break;
          }
          vider_buffer();
        }
        else if(std::cin.fail()){
          std::cerr << "Erreur, saisie incorrecte." << std::endl;
          vider_buffer();
        }
        break;
      }
    }
     
    bool saisir_int(int &variable, const std::string &message){
      std::string temp;
      while(true){
        std::cout << message;
        std::cin >> temp;
        if(std::cin.bad() || std::cin.eof()){
          std::cerr<<"Une erreur interne est survenue." << std::endl;
          if(std::cin.eof()){
    	return false;
          }
          vider_buffer();
          continue;
        }
        else if(std::cin.fail()){
          std::cerr << "Erreur, saisie incorrecte." << std::endl;
          vider_buffer();
          continue;
        }
        vider_buffer();
        std::istringstream stream(temp);
        stream >> variable;
        if(stream.fail() || !stream.eof()){
          std::cerr << "Erreur, saisie incorrecte." << std::endl;
        }
        else{
          return true;
        }
      }
      return false;
    }
     
     
    void vider_buffer(){
      std::cin.clear();
      std::cin.seekg(0, std::ios::end);
      if(!std::cin.fail()){
        std::cin.ignore(std::numeric_limits<std::streamsize>::max());
      }
      else
        std::cin.clear();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    entrez un nombre: 3
    entrez une chaine
    j'ai trouvé ces fonctions ici:
    http://sdz.tdct.org/sdz/la-saisie-securisee-en-c.html

    quelqu'un a une idée?

  2. #2
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut
    Je me suis peut-être mal expliqué.
    la ligne std::getline(std::cin, variable); est ignorée à l’exécution. variable est affecté de la chaine vide.
    j'aurai besoin de saisir une chaine après avoir saisi un entier
    quelqu'un aurai une idée?

  3. #3
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut
    si j'ajoute vider_buffer avant la saisie de la chaîne, cela ne change rien

    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
    void saisir_string(std::string &variable, const std::string &message){
      while(true){
        std::cout << message;
        vider_buffer();
        std::getline(std::cin, variable); 
        if(std::cin.bad() || std::cin.eof()){
          std::cerr << "Erreur, saisie incorrecte." << std::endl;
          if(std::cin.eof()){
    	break;
          }
          vider_buffer();
        }
        else if(std::cin.fail()){
          std::cerr << "Erreur, saisie incorrecte." << std::endl;
          vider_buffer();
        }
        break;
      }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void vider_buffer(){
      std::cin.clear();
      std::cin.seekg(0, std::ios::end);
      if(!std::cin.fail()){
        std::cin.ignore(std::numeric_limits<std::streamsize>::max());
      }
      else
        std::cin.clear();
    }
    une idée?

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Les fonctions de saisie sont inutilement complexes. Entre autre avec des std::endl sur std::cerr qui n'est pas bufférisé, pas de std::flush après les std::cout!

    Quant à la fonction vider_buffer(), elle utilise seekg() qui n'a pas de sens sur un un flux. Il faudrait plus simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void vider_buffer(){
      std::cin.clear();
      std::cin.ignore( std::numeric_limits<std:streamsize>::max() );
    }

  5. #5
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut
    Merci pour la réponse.

    Avec le vider_buffer que tu me propose, le message "entrez une chaine" ne s'affiche plus. Le programme lit un entier et ne passe pas à la suite.

    mes saisies compliquées sont expliqués ici:http://sdz.tdct.org/sdz/la-saisie-securisee-en-c.html

    sinon,j'ai le même problème avec ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <iostream>
     
    int main(){
      int n;
      std::cout<<"entrez un nombre"<<std::endl<<std::flush;
      std::cin>>n;
      std::cout<<"entrez une chaine"<<std::endl<<std::flush;
      std::string X;
      std::getline(std::cin,X);
      std::cout<<X<<std::endl<<std::flush;
    }
    quand il demande une chaîne, getline est zappée et X ne contient rien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ ./a.out 
    entrez un nombre
    5
    entrez une chaine
     
    $
    une idée?

  6. #6
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut
    Ça marche avec std::cin.ignore:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream>
     
    int main(){
      int n;
      std::cout<<"entrez un nombre"<<std::endl<<std::flush;
      std::cin>>n;
      std::cout<<"entrez une chaine"<<std::endl<<std::flush;
      std::string X;
      std::cin.ignore();
      std::getline(std::cin,X);
      std::cout<<X<<std::endl<<std::flush;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ ./a.out 
    entrez un nombre
    54
    entrez une chaine
    bonjour toi
    bonjour toi

  7. #7
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut
    J'ai abandonné les saisies compliquées car ça ne marchait toujours pas. Voici la dernière version:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "partie.hpp"
     
    int main(){
      partie jeu;
    }
    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 <vector>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <random>
     
    #include "partie.hpp"
     
    partie::partie(){
      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_int_distribution<int> distrib_profession(0,11);
      int choix;
      do{
        std::cout<<"Combien de joueurs pour cette partie? "<<std::endl<<std::flush;
        std::cin>>choix;
        if(choix<1||choix>6)
          std::cout<<"le nombre de joeurs doit être compris enetre 1 et 6"<<std::endl;
      }while(choix<1||choix>6);
      std::string nom_joueur;
      int numero_profession;
      std::vector<int>profession_utilisee;
      for(int i=0;i<choix;i++){
        std::cout<<"nom du joueur "<<i+1<<": ";
        std::cin.ignore();
        std::cin>>nom_joueur;
        do
          numero_profession=distrib_profession(gen);
        while ( find(profession_utilisee.begin(),profession_utilisee.end(),numero_profession) != profession_utilisee.end());
        profession_utilisee.push_back(numero_profession);
        std::cout<<"Joueur "<<nom_joueur<<", votre profession est "<<liste_professions[numero_profession]<<std::endl;
        joueur temp(liste_professions[numero_profession]);
        liste_joueurs.push_back(temp);
        liste_noms.push_back(nom_joueur);
      }
    }

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    Par défaut
    L'autre solution étant de ne faire que des getline(), puis faire tes conversions sur la ligne saisie avec un istringstream.
    Avec ça, tu ne devrais plus avoir de soucis de caractères "laissés" dans le flux d'entrée.
    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.

  9. #9
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut
    un exemple?

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    Par défaut
    Un 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
    #include <iostream>
    #include <string>
    #include <sstream>
     
    int getline_main(){
    	int n;
    	std::string line;
    	std::cout<<"entrez un nombre"<<std::endl; //De mémoire, endl implique déjà flush
    	std::getline(std::cin, line);
    	std::istringstream(line) >> n;
    	std::cout<<"entrez une chaine"<<std::endl;
    	std::string X;
    	std::getline(std::cin,X);
    	std::cout<<X<<std::endl;
    	return EXIT_SUCCESS;
    }
    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.

  11. #11
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut
    oui ça marche

  12. #12
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 287
    Par défaut
    Problème classique d'enchainement de getline après >>. La question est traitée dans la FAQ (comme plusieurs des autres que tu as postées)

    https://cpp.developpez.com/faq/cpp/?...ligne-soit-lue
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  13. #13
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16

  14. #14
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 287
    Par défaut
    Que de la même façon, j'avais mis dans la FAQ il y a fort longtemps tout ce qu'il faut pour vérifier les saisies clavier.
    Sinon, trop de mots et pas lisible l'article. Parle de choses inutiles (seekg()), et d'autres à bannir (std::istream::getline -- à ne pas confondre avec std::getline)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  15. #15
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 391
    Billets dans le blog
    16
    Par défaut
    Merci pour les précisions, je prend note

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

Discussions similaires

  1. Saisie de String.
    Par kek_8 dans le forum Java ME
    Réponses: 3
    Dernier message: 20/03/2008, 18h43
  2. remplir un champs dans HSQL avec un String saisi
    Par lampoulchon dans le forum JDBC
    Réponses: 3
    Dernier message: 01/02/2008, 19h30
  3. saisi d'un String entier
    Par ke2007 dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 19/08/2007, 12h12
  4. Problème getline(ifstream, string)
    Par OliverSleep dans le forum C++Builder
    Réponses: 2
    Dernier message: 24/05/2007, 17h09
  5. getline string integer
    Par Gebudi. dans le forum C++
    Réponses: 9
    Dernier message: 28/05/2006, 08h23

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