C++ : ostringstream 1

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Autres langues :anglais 100% • ‎français 100%

C++ : construire plus facilement des chaînes formatées avec ostringstream

Dans notre rubrique Trucs et astuces, nous avons présenté une classe Logger servant à tenir un journal d'exécution. Celui-ci fonctionne plutôt bien, mais il lui manque un élément important : le formatage des messages. Voyez l'exemple de la fonction syslog (outil de journalisation des messages du système sur Unix) :

void syslog(int priority, const char* format, .../*arguments*/);

On peut appeler cette fonction avec un nombre variable de paramètres, à la manière de printf et ses variantes. Le message résultant est construit à l'aide des expressions de formatage « %... » :

syslog(LOG_ERR, "ldap_open(%s %u) failed", MY_LDAP_SERVER, LDAP_PORT);

La classe Logger n'offre pas cette flexibilité. La chaîne de caractères qu'on lui donne est écrite textuellement dans le journal, sans possibilité de formatage. Cependant, il est possible de faire encore mieux que syslog en utilisant la classe ostringstream. La classe StringStream définie ci-dessous, dérivée de ostringstream, nous donne toute la flexibilité nécessaire. En surchargeant les opérateurs d'insertion << et de conversion string(), on peut bâtir une chaîne de complexité arbitraire et la convertir en objet string en une seule expression.

Fichier : stringstream.cpp
#include <sstream>
 
using namespace std;
 
class StringStream : public ostringstream
{
public:
    // -----------------------------------------------------------------
    // Overloaded insertion operators to replace those defined in
    // ostream. We want << to return StringStream& instead of ostream&.
    // -----------------------------------------------------------------
 
    // insertion of standard and user defined data-types
    template <class T>
    StringStream& operator << (T item);
 
    // insertion of stream manipulators (cannot be instantiated
    // with template above)
    StringStream& operator << (ostream& (*manipulator)(ostream&));
 
    // -----------------------------------------------------------
    // Overloaded casting operator for string.
    // -----------------------------------------------------------
    operator string();
};
 
// --------------------------------------
// operator implementations
// --------------------------------------
 
template <class T>
StringStream& StringStream::operator <<  (T item)
{
    *(ostringstream*)this << item;
    return *this;
}
 
StringStream& StringStream::operator << (ostream& (*manipulator)(ostream&))
{
    *(ostringstream*)this << manipulator;
    return *this;
}
 
StringStream::operator string()
{
    return str();
}


Cet extrait illustre bien la pertinence de StringStream dans un appel à LOGGER_WRITE :

LOGGER_WRITE(Logger::INFO,
             StringStream() << endl << "---------------------------"
                            << endl << "pi = "
                                    << setw(20) << right << scientific << M_PI
                            << endl << Sphere()
                            << endl << "---------------------------")
Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Ressources de Calcul Québec
Outils
Partager