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

SL & STL C++ Discussion :

ostringstream( const string&, openmode ) et ios::app


Sujet :

SL & STL C++

  1. #1
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut ostringstream( const string&, openmode ) et ios::app
    Bonjour à tous.

    Un point me turlupine à propos de la classe ostringstream. Voici l'un des constructeurs disponibles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    explicit basic_ostringstream(
    const basic_string<charT,traits,Allocator>& str,
    ios_base::openmode which = ios_base::out);
    Naïvement, je pensais pouvoir l'utiliser comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ostringstream ostr( "abdc", ios::out | ios::app );
    ostr << "1" << "2";
    cout << ostr.str().c_str() << endl;
    avec une sortie telle que : "abcd12".
    Or, la sortie que j'obtiens est : "12cd". Le ios::app a été ignoré par le constructeur. Je ne te trouve aucune indication là-dessus dans le Standard. Un détail m'aurait-il échappé ????

  2. #2
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2006
    Messages : 58
    Points : 74
    Points
    74
    Par défaut
    A mon avis lors de l'entrée dans le constructeur de ostringstream, le compilateur crée un objet temporaire string("abcd"). A la sortie du constructeur, donc avant la ligne qui utilise l'opérateur <<, l'objet temporaire est détruit.

    A partir de cet instant la mémoire est donc corrompue et le résultat de tes opérateurs << imprévisible, d'où ta sortie bizarre.

  3. #3
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 31
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par touco
    A mon avis lors de l'entrée dans le constructeur de ostringstream, le compilateur crée un objet temporaire string("abcd"). A la sortie du constructeur, donc avant la ligne qui utilise l'opérateur <<, l'objet temporaire est détruit.

    A partir de cet instant la mémoire est donc corrompue et le résultat de tes opérateurs << imprévisible, d'où ta sortie bizarre.
    Ca peut être ça puisque ton code est correct...

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Citation Envoyé par touco
    A mon avis lors de l'entrée dans le constructeur de ostringstream, le compilateur crée un objet temporaire string("abcd"). A la sortie du constructeur, donc avant la ligne qui utilise l'opérateur <<, l'objet temporaire est détruit.

    A partir de cet instant la mémoire est donc corrompue et le résultat de tes opérateurs << imprévisible, d'où ta sortie bizarre.
    ostringstream est bien assez futé pour faire une copie de la chaîne, donc rien à voir.

    Je suppose que tu as une bonne raison de ne pas écrire ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ostringstream ostr(ios::app); // le ios::out est redondant
    ostr  << "abdc" << "1" << "2";
    Sinon tu peux toujours placer toi-même le curseur d'écriture à la fin du flux avec la fonction membre setp.

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Tu as essayé ios::ate comme flag d'ouverture ?

  6. #6
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Citation Envoyé par Loulou24
    Je suppose que tu as une bonne raison de ne pas écrire ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ostringstream ostr("", ios::out | ios::app );
    ostr  << "abdc" << "1" << "2";
    Aucune bonne raison D'ailleurs, c'est bien ce que j'écris, in fine. Simplement, je crois que les décisions de design de la STL sont généralement assez bien motivées.Or, la motivation de celle-ci ne m'apparaît pas clairement, d'où ma question. Car enfin, je ne trouve guère intuitif de penser que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ostringstream ostr1( "ab", ios::out | ios::app ); ostr1 << 1 << 2;
    ostringstream ostr1(); ostr1 << 1 << 2;
    ostringstream ostr1(  ""  ); ostr1 << 1 << 2;
    donnent toutes les 3 exactement la même sortie...

  7. #7
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2006
    Messages : 58
    Points : 74
    Points
    74
    Par défaut
    ostringstream est bien assez futé pour faire une copie de la chaîne, donc rien à voir.
    A mon avis, non. La spécification du constructeur dit que str n'est pas une chaine, mais une référence sur une chaine, je suppose que c'est pour permettre à l'utilisateur de ostringstream d'utiliser (et d'allouer) sa chaine. Dans le cas présent passer une référence sur un objet temporaire au constructeur est donc potentiellement dangereux.

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    A mon avis, non. La spécification du constructeur dit que str n'est pas une chaine, mais une référence sur une chaine, je suppose que c'est pour permettre à l'utilisateur de ostringstream d'utiliser (et d'allouer) sa chaine. Dans le cas présent passer une référence sur un objet temporaire au constructeur est donc potentiellement dangereux.
    Ce qu'il ne faut pas entendre... Les flux ne fonctionnent pas comme ça, et même si c'était le cas alors ce ne serait certainement pas une référence constante qui serait prise en paramètre.
    Il ne faut pas raisonner comme cela à chaque fois que tu croises une référence constante, la plupart du temps c'est simplement pour éviter une copie inutile, rien de plus.

    A part ça, je me repete car je crois que nos posts se sont croisés :

    Tu as essayé ios::ate comme flag d'ouverture ?

  9. #9
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Oui, ios::ate ne change rien sur mes tests...

    En fait, je me demande si ce paramètre const basic_string<charT,traits,Allocator>& str ne sert pas juste de prototype. Car après tout, rien ne nous interdit de passer à ostringstream autre chose qu'une std::string. Une string case-insensitive utilisant un autre charTraits par exemple.

    En ce cas, l'argument prototype ne sert qu'à obtenir un clone pour la tambouille interne. Son contenu (la chaine de caractères elle-même) est ignoré. Ca doit être vérifiable dans les sources de <string>, mais je ferai ça plus tard. A cette heure, c'est le wikende

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Bof. Pour moi la doc est claire, ça devrait initialiser la chaîne du flux

    explicit ostringstream ( openmode mode = out );
    explicit ostringstream ( const string & str, openmode mode = out );

    Construct an object and optionally initialize string content.
    Constructs an object of class ostringstream including the initialization of the associated stringbuf object and the call to its base class' constructor with the stringbuf object as constructor parameter.
    Additionally, in case the second constructor syntax is used, the stream's buffer is initialized with the content of the STL string object str as if a call to member str.
    En fait, je me demande si ce paramètre const basic_string<charT,traits,Allocator>& str ne sert pas juste de prototype. Car après tout, rien ne nous interdit de passer à ostringstream autre chose qu'une std::string. Une string case-insensitive utilisant un autre charTraits par exemple.
    A mon avis ces paramètres templates sont les mêmes que ceux du flux, à savoir que pour passer une string case insensitive il faudra avoir déclaré un flux case insensitive (avec le même CharTraits).

  11. #11
    Membre averti
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Points : 307
    Points
    307
    Par défaut
    Ca ressemble à un bug de la lib de ton compilo.

    Pour info, ton code fonctionne avec VC2005 et g++ 4.0.1
    mais pas avec VC2003.

Discussions similaires

  1. const string &
    Par ABAM3194 dans le forum C++
    Réponses: 2
    Dernier message: 17/01/2014, 10h31
  2. le developpement des ios app en windows
    Par jyson dans le forum Développement iOS
    Réponses: 3
    Dernier message: 30/08/2013, 23h35
  3. Réponses: 2
    Dernier message: 25/10/2010, 16h02
  4. Problème avec ofstream et ios::app
    Par Clad3 dans le forum SL & STL
    Réponses: 8
    Dernier message: 07/01/2007, 12h10

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