web-dev-qa-db-fra.com

Comment réutiliser un ostringstream?

Je voudrais effacer et réutiliser un ostringstream (et le tampon sous-jacent) afin que mon application n'ait pas à faire autant d'allocations. Comment réinitialiser l'objet à son état initial?

115
twk

J'ai utilisé une séquence de clear et str dans le passé:

// clear, because eof or other bits may be still set. 
s.clear();
s.str("");

Ce qui a fait l'affaire pour les chaînes de chaînes d'entrée et de sortie. Vous pouvez également effacer manuellement, puis rechercher la séquence appropriée au début:

s.clear();
s.seekp(0); // for outputs: seek put ptr to start
s.seekg(0); // for inputs: seek get ptr to start

Cela empêchera certaines réallocations effectuées par str en écrasant ce qui se trouve actuellement dans le tampon de sortie. Les résultats sont comme ceci:

std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b";
assert(s.str() == "bello");

Si vous souhaitez utiliser la chaîne pour les fonctions c, vous pouvez utiliser std::ends, mettant un null de terminaison comme ceci:

std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b" << std::ends;
assert(s.str().size() == 5 && std::strlen(s.str().data()) == 1);

std::ends est une relique des obsolètes std::strstream, qui a pu écrire directement dans un tableau de caractères que vous avez alloué sur la pile. Vous avez dû insérer manuellement un nul final. Toutefois, std::ends n'est pas obsolète, je pense parce qu'il est toujours utile comme dans les cas ci-dessus.

151

Il semble que l'appel ostr.str("") fait l'affaire.

5
Diego Sevilla

Si vous souhaitez effacer le tampon d'une manière qui entraînera son effacement avant sa première utilisation, vous devrez d'abord ajouter quelque chose au tampon avec MSVC.

struct Foo {
    std::ostringstream d_str;
    Foo() { 
        d_str << std::ends;   // Add this
    }
    void StrFunc(const char *);
    template<class T>
    inline void StrIt(const T &value) {
        d_str.clear();
        d_str.seekp(0);  // Or else you'll get an error with this seek
        d_str << value << std::ends;
        StrFunc(d_str.str().c_str());  // And your string will be empty
    }
};
2
Unkle George

Non. Pour plus de clarté, utilisez deux flux nommés différemment et laissez le compilateur d'optimisation comprendre qu'il peut réutiliser l'ancien.

0