Gibt es eine sprintf ähnliche Funktion für std::string ???



  • Gibt es eine sprintf Funktion für std::string ohne den Umweg über char[] gehen zu müssen ??? 🙂


  • Mod

    Was genau meinst du mit ähnlich? Das übliche wäre die Benutzung von Stringstreams um diese Art von Aufgaben zu erledigen, aber die Art und Weise der Benutzung ist natürlich komplett anders.





  • @SeppJ:
    Naja, ich suche im Endeffekt eine sprintf Funktion für std::string;

    Also folgendens:

    std::string S = "";
    
    mysprintf(S, "Koordinaten des Punktes: (%03i %03i)", x, y);
    

    @scrontch:
    Cool, die Funktion ist genau das was ich suchte. Gibt es die Funktion auch in Standard C++ ?



  • Wenn du nur die Argumente ersetzen willst, kannst du das einfach && typsicher mit C++0x (variadic templates) machen.


  • Mod

    Bitte ein Bit schrieb:

    @scrontch:
    Cool, die Funktion ist genau das was ich suchte. Gibt es die Funktion auch in Standard C++ ?

    Nein.



  • #include <string>
    #include <cstdarg>
    #include <cstdio>
    #include <cctype>
    
    std::string str_printf (const char* format, ...)
    {
        using namespace std;
    
        std::va_list args;
        std::string retval;
    
        va_start (args, format);
        retval.resize (vsnprintf (0, 0, format, args));
        vsnprintf (&retval[0], retval.size () + 1, format, args);
        va_end (args);
    
        return retval;
    }
    


  • Bitte ein Bit schrieb:

    std::string S = "";
    
    mysprintf(S, "Koordinaten des Punktes: (%03i %03i)", x, y);
    

    was spricht gegen

    std::ostringstream ostr;
    ostr << "Koordinaten des Punktes: (" << << setfill('0') << setw(3) << x << ' ' << y << ')';
    std:.string S = ostr.str();
    

    (ungetestet)



  • void print(std::ostream& s, const char* str)
    {
            s << str;
    }
    
    template <typename Head, typename... Tail>
    void print(std::ostream& s, const char* str, Head&& head, Tail&&... tail)
    {
            while(*str != '%')
                    s << *str++;
            s << head;
    
            print(s, ++str, std::forward<Tail>(tail)...);
    }
    
    template <typename... Args>
    std::string print(const std::string& format, Args&&... args)
    {
            std::ostringstream ss;
            print(ss, format.c_str(), std::forward<Args>(args)...);
            return ss.str();
    }
    

    Sicherlich nicht das schnellste, aber typsicher.



  • pumuckl schrieb:

    was spricht gegen

    Es ist unübersichtlich, doppelt so lang und macht es unmöglich, den String mit gettext() o.ä. zu lokalisieren?



  • 314159265358979 schrieb:

    void print(std::ostream& s, const char* str)
    {
            s << str;
    }
     
    template <typename Head, typename... Tail>
    void print(std::ostream& s, const char* str, Head&& head, Tail&&... tail)
    {
            while(*str != '%')
                    s << *str++;
            s << head;
     
            print(s, ++str, std::forward<Tail>(tail)...);
    }
     
    template <typename... Args>
    std::string print(std::string format, Args&&... args)
    {
            std::stringstream ss;
            print(ss, format.c_str(), std::forward<Args>(args)...);
            return ss.str();
    }
    

    Sicherlich nicht das schnellste, aber typsicher.

    Das meiste passiert doch zur Compiletime oder nicht?



  • Weil ich std::ostringstream verwende 😉
    (Übrigens habe ich meinen Post noch 2 mal editiert, einmal const string& und das zweite mal ostringstream.)



  • audacia schrieb:

    pumuckl schrieb:

    was spricht gegen

    Es ist unübersichtlich, doppelt so lang und macht es unmöglich, den String mit gettext() o.ä. zu lokalisieren?

    Wenn Du das unübersichtlich findest, dann muss Dir ganz C++ unübersichtlich erscheinen. Die Lokalisation des Strings halte ich für unnötig, wozu sollte man das brauchen?

    Pi*10^wasauchimmer:
    Wo liegt der Vorteil ggü. pumuckls Code?



  • Eisflamme schrieb:

    Wenn Du das unübersichtlich findest, dann muss Dir ganz C++ unübersichtlich erscheinen.

    So ist es. Aber wieso meinst du das?

    Eisflamme schrieb:

    Die Lokalisation des Strings halte ich für unnötig, wozu sollte man das brauchen?

    Ist jetzt nicht dein Ernst, oder?



  • Der Voteil meines Codes ist die Übersichtlichkeit, sonst gar nichts 😉



  • Ich find pumuckls Code weit übersichtlicher. 🙂

    audacia:
    In C++ baut man vieles durch solche Streams auf. Das mag Dir unorthodox erscheinen, wenn Du damit nicht vertraut bist, tatsächlich hat es aber viele Vorteile. Letztlich kann man sich sehr gut an die Syntax gewöhnen, was er mir wert ist, wenn ich dafür Streams nutzen darf.

    Und ja, es ist mein Ernst. Aber ich muss zugeben, dass ich gar nicht verstehe, was du mit Lokalisation des Strings meinst. Erklärst Du es mir oder kriege ich auf den Post nur eine weitere rhetorische Frage? 😉



  • std::cout << print("% + % = %", 4, 5, 42);
    

    Also ich finde das übersichtlicher als:

    std::cout << 3 << " + " << 5 << " = " << 42;
    

    😃



  • Mir gefällt daran nicht, dass die Reihenfolge der Elemente vertauscht wird. Die 4 erscheint nach dem +, obwohl sie davor kommt. Bei << hat man zwar den ganzen Ausdruck nicht auf einen Blick mit Variablen, dafür sieht man aber bereits alle Elemente, kann von links nach rechts lesen ohne zwischendurch zu springen und hat den Ausdruck nur etwas aufgebläht. Die Alternative ist mir lieber, aber jedem das seine.



  • Möglichkeit #3: http://ideone.com/cMlRb
    🙂



  • Man kann operator, überladen?

    Das ist cool, aber die Syntax ist jetzt nicht C++-like. Du hast jetzt << durch , ersetzt. So schlimm finde ich << einfach nicht. Es gibt mir das Gefühl von Bewegung und Dynamik und da ich sonst nur faul rumsitze, befriedigt das mein Gewissen. Ist C++ nicht einfach toll? :p


Log in to reply