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 :

Concaténation de chaîne


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut Concaténation de chaîne
    Hello,

    Disons que vous avez régulièrement besoin d'effectuer des concaténations de chaînes, par exemple pour des messages d'exception.

    Il existe plusieurs méthodes, dont :

    1. utilisation de l'opérateur +
    2. utilisation de append
    3. utilisation d'un ostringstream


    Je me retrouve dans un projet où la première solution est systématiquement utilisée.
    Elle est réputée peu performante (création d'un nouvel objet string à chaque application d'une opération +). Toutefois, les flux ne sont pas non plus très réputés, point de vue performances.
    La seconde est sans doute la plus rapide, mais la moins "présentable".

    Qu'utilisez-vous, de votre côté ?

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Salut,

    en terme de perf, le préprocesseur au maximum, sinon l'opérateur += d'une classe string faute de mieux.
    Les flux rarement.
    De toutes façons il faut bien en utiliser un, et si c'est uniquement pour générer des messages d'erreur, les perfs sont carrément secondaires, à moins que tu en aies beaucoup, auquel cas tu as un autre problème bien plus important.
    Si tu réalises régulièrement des concaténations diverses, peut-être qu'un autre format que la chaîne de caractères pour passer l'information est préférable.
    Sinon, utilises un buffer. std::string a une interface reserve.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Le jour où ce sont les concaténations de chaines qui seront le problème de performances, je me poserai la question.

    Une exception ne devant survenir que lors de problèmes anormaux, sa gestion est toujours faite en remontant à un fonctionnement plus lent: intervention utilisateur, abandon du processus en cours, arrêt du programme.
    Dans tous les cas, on sort du flux de calculs rapides, et le manque de performance n'est pas grave.

    Avec un ostringstream, on peut réserver une certaine capacité, supprimant les besoins de réallocation à chaque chaine concaténée.
    Le seul défaut concret d'un ostringstream, c'est qu'on perd sa nature de ostringstream après le premier appel à <<.
    Cela empèche de chainer l'appel à str() et donc son utilisation dans une expression.

    Il suffit de faire une petite capsule autour pour que ce ne soit plus le cas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct capsule {
    std::ostringstream stream;
     
    template <typename T>
    capsule& operator << (T const& t) { stream << t; return *this; }
     
    operator std::string () const { return stream.str(); }
    };
     
    voif f() { throw std::runtime_error(capsule{} << "un probleme est survenu avec " << "id" << " dans la fonction f"); }
    A améliorer, bien sûr, mais ca fait la base.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    C'est vrai que les yeux irrités par ces additions de chaînes, je n'avais pas pris conscience du caractère exceptionnel de la chose dans l'exécution du code, et que ce n'est peut-être pas si important.

    Toutefois, pour en rester aux considérations théoriques, une chose m'intrigue :

    Citation Envoyé par ternel Voir le message
    Le seul défaut concret d'un ostringstream, c'est qu'on perd sa nature de ostringstream après le premier appel à <<.
    Cela empèche de chainer l'appel à str() et donc son utilisation dans une expression.
    Il faut juste appeler str() sur une instruction à part.

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Oui, certes. Et, il faut aussi définir le stream encore à part.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    voif f(int a, int b) {
        if ( bad(a, b) ) {
            throw std::runtime_error(capsule{} << "illegal values (" << a << ", " << b << ").");
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    voif f(int a, int b) {
        if ( bad(a, b) ) {
            std::ostringstream s;
            s << "illegal values (" << a << ", " << b << ").":
            throw std::runtime_error(s.str());
        }
    }
    Dans la première version, le bruit technique est plus restreint.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Ah, OK. je n'avais pas compris ce que tu avais à l'esprit.

    Merci pour l'astuce.

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

Discussions similaires

  1. Concaténation de chaînes de caractères
    Par Sakapatate dans le forum Débuter
    Réponses: 15
    Dernier message: 16/06/2007, 22h19
  2. Concaténation de chaîne de caractères
    Par Ardely dans le forum Delphi
    Réponses: 6
    Dernier message: 31/01/2007, 19h10
  3. Comment concaténer des chaînes issues d'un fichier ini ?
    Par Neit_Sabes dans le forum Framework .NET
    Réponses: 10
    Dernier message: 27/09/2006, 09h28
  4. concaténation de chaîne de caractère
    Par jh0483 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 08/08/2005, 17h10
  5. [XSLT 1.0] Concaténation de chaînes
    Par tofita_49 dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 25/07/2005, 18h34

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