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 :

sstream et saisie cin


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    436
    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 : 436
    Billets dans le blog
    16
    Par défaut sstream et saisie cin
    Bonjour,

    pourquoi b est toujours à 0 ?

    une idée ?

    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
    #include <iostream>
    #include <string>
    #include <sstream>
     
    int main(){
      std::cout<<"a= ";
      int a;
      std::string saisie;
      std::stringstream geek;
      std::cin>>saisie;
      geek<<saisie;
      geek>>a;
      geek.flush();
      std::cout<<"b= ";
      int b;
      std::cin>>saisie;
      geek<<saisie;
      geek>>b;
      std::cout<<a<<' '<<b<<std::endl;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ ./a.out 
    a= 56
    b= 12
    56 0

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 551
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 551
    Par défaut
    Coincé par les CR-LF ?

  3. #3
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 305
    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 305
    Par défaut
    Hum...

    Je n'utilise jamais les stringstream en I/O. J'utilise uniquement l'un ou l'autre.

    Quant au reset, je fais ça avec `iss.str("")`, voire directement dans ton cas avec `iss.str(saisie)`.

    Au passage, toujours tester les extractions. Ca permettrait de savoir quand cela commence à ne plus aller.
    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...

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 705
    Par défaut
    Hello,

    Le problème vient du fait que geek.flush() ne sert pas à réinitialiser le flux pour une réutilisation.

    Chronologie dans votre programme :

    • geek << saisie("56") : Le flux contient "56".
    • geek >> a : Le flux lit "56". Il arrive à la fin de la chaîne interne. Le drapeau eofbit (End Of File) est levé.
    • geek.flush() : Cette commande synchronise les tampons de sortie, mais elle n'efface pas les drapeaux d'erreur (EOF) et ne vide pas le contenu lu.
    • geek << saisie("12") : Vous ajoutez "12" au flux. Le flux contient maintenant techniquement "12" (ou une suite selon la position), mais il est toujours considéré comme "en erreur/fini" à cause du eofbit.
    • geek >> b : Comme le drapeau EOF (ou failbit) est actif, l'opération de lecture refuse de s'exécuter. b n'est pas modifié et reste à 0.


    Pour réutiliser un stringstream, vous devez faire deux choses :

    • geek.clear() : Pour remettre les drapeaux d'état (comme EOF) à zéro.
    • geek.str("") : Pour vider le texte précédent du tampon (sinon vous allez ajouter "12" à la suite de l'ancien contenu s'il n'a pas été entièrement consommé).


    Une proposition de code corrigé,

    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
    #include <iostream>
    #include <string>
    #include <sstream>
     
    int main(){
        std::cout << "a= ";
        int a;
        std::string saisie;
        std::stringstream geek;
     
        // Première lecture
        std::cin >> saisie;
        geek << saisie;
        geek >> a;
     
        // --- CORRECTION ICI ---
        geek.clear();  // 1. Réinitialise les drapeaux d'erreur/EOF
        geek.str("");  // 2. Vide le contenu du buffer
        // ----------------------
     
        std::cout << "b= ";
        int b;
        std::cin >> saisie;
        geek << saisie; // Maintenant le flux est propre et prêt
        geek >> b;
     
        std::cout << a << ' ' << b << std::endl;
     
        return 0;
    }
    Si vous n'êtes pas contraint d'utiliser stringstream pour un exercice,
    l'approche moderne en C++ (depuis C++11) pour convertir une string en intest d'utiliser std::stoi.

    C'est plus simple et évite ces problèmes d'état :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Remplacer toute la mécanique stringstream par :
    std::cin >> saisie;
    a = std::stoi(saisie);
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

Discussions similaires

  1. flux de saisie : fichier ou cin au choix
    Par ternel dans le forum C++
    Réponses: 3
    Dernier message: 24/06/2014, 19h27
  2. Bloquer saisie cin>> à 1 caractère: possible?
    Par Christophe59 dans le forum C++
    Réponses: 1
    Dernier message: 22/03/2009, 22h24
  3. Problème parasitage tampon saisie cin
    Par pjtuloup dans le forum C++
    Réponses: 7
    Dernier message: 25/05/2008, 09h25
  4. Réponses: 2
    Dernier message: 10/03/2008, 13h08
  5. [cin] saisie avec test
    Par crakocrako dans le forum C++
    Réponses: 1
    Dernier message: 27/02/2008, 11h23

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