sprintf für string



  • Hallo,

    in meinem Code muss ich sehr oft formatiert in einen std::string schreiben:

    char errorDescr[200];
    sprintf_s(errorDescr, 200,"Error: %s %i\n", shaderError->GetBufferPointer(), cnt);
    error = errorDescr;
    

    error ist ein std::string. Im Moment mache ich das wie man sieht über den Umweg eines c-Arrays und sprintf_s. Ich finde das aber recht lästig und würde das gerne in einem Einzeiler oder so abfertigen.
    Irgendwie sowas in der Art:

    std::string s;
    s.writeFormated("foo %i %s\n", moep, var);
    

    Gibts da irgendwas fertiges in C++?





  • Stringstreams.

    std::stringstream errorstream;
    errorstream << "Error " << moep << ' ' << var << '\n';
    std::string error = errorstream.str();
    


  • stringer schrieb:

    Gibts da irgendwas fertiges in C++?

    Nein, aber wir hatten das Thema gerade:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-245524.html

    Edit: Über zwei Minuten 😮

    @pumuckl: das ist kein Einzeiler 😉



  • audacia schrieb:

    @pumuckl: das ist kein Einzeiler 😉

    In der Tat seh ich da jetzt keine Verbesserung. Ich hätte schon gerne die flexiblen Möglichkeiten von printf(). Diese stringstream Syntax is ja doch recht frickelig/geschwätzig (wenn ich zb. Einen float auf 5 Stellen mit 2 Nachkommastellen ausgeben will etc. 😕



  • audacia schrieb:

    @pumuckl: das ist kein Einzeiler 😉

    std::string error = static_cast<std::stringstream&>(std::stringstream() << "Error " << moep << ' ' << var << '\n').str();
    

    🙄



  • stringer schrieb:

    audacia schrieb:

    @pumuckl: das ist kein Einzeiler 😉

    In der Tat seh ich da jetzt keine Verbesserung. Ich hätte schon gerne die flexiblen Möglichkeiten von printf(). Diese stringstream Syntax is ja doch recht frickelig/geschwätzig (wenn ich zb. Einen float auf 5 Stellen mit 2 Nachkommastellen ausgeben will etc. 😕

    Wenns nur ums ausgeben geht, nimm einfach cout und reihe es hintereinander. Für cout gibt es auch manipulatoren je nach dem wie viel stellen du willst:

    cout << "Mein Hund ist " << 13 << " Jahre alt!" << endl;
    


  • stringer schrieb:

    frickelig/geschwätzig

    .../typunsicher/bufferüberlaufanfällig/formatvertipperanfällig/unlesbar bei größeren Ausgaben/...



  • pumuckl schrieb:

    audacia schrieb:

    @pumuckl: das ist kein Einzeiler 😉

    std::string error = static_cast<std::stringstream&>(std::stringstream() << "Error " << moep << ' ' << var << '\n').str();
    

    🙄

    Warum ist denn da ein static_cast von nöten? 😕



  • stringer schrieb:

    Ich hätte schon gerne die flexiblen Möglichkeiten von printf().

    Dann nimm sie und arbeite mit C-Strings. Nimm aber auch die damit verbundenen Probleme in Kauf und wundere dich nicht bei merkwürdigem Programmverhalten.

    PS: Jaja, Hauptsache, wir entfachen den beliebten "C-Funktionen vs C++-Streams"-Flamewar ein weiteres Mal. 😃



  • Nexus schrieb:

    stringer schrieb:

    Ich hätte schon gerne die flexiblen Möglichkeiten von printf().

    Dann nimm sie und arbeite mit C-Strings. Nimm aber auch die damit verbundenen Probleme in Kauf und wundere dich nicht bei merkwürdigem Programmverhalten.

    Könntest du mir das genauer erkläreen?



  • Pigeon schrieb:

    Warum ist denn da ein static_cast von nöten? 😕

    Weil der op<< eine freie Funktion ist, die ein std::ostream& zurückgibt - und std::ostream hat keine str()-Methode.



  • pumuckl schrieb:

    stringer schrieb:

    frickelig/geschwätzig

    .../typunsicher/bufferüberlaufanfällig/formatvertipperanfällig/unlesbar bei größeren Ausgaben/...

    Läßt sich alles vermeiden, sogar automatisch, von der subjektiven Unleserlichkeit abgesehen.

    Nexus schrieb:

    PS: Jaja, Hauptsache, wir entfachen den beliebten "C-Funktionen vs C++-Streams"-Flamewar ein weiteres Mal. 😃

    Der Verweis auf den anderen Thread war ja sogar die erste Reaktion. Das Schließen des Threads zu diesem Zeitpunkt hätte nicht geschadet.



  • pumuckl schrieb:

    std::string error = static_cast<std::stringstream&>(std::stringstream() << "Error " << moep << ' ' << var << '\n').str();
    

    Ich möchte wetten, das hast Du nicht ausprobiert. 😉



  • Hossenscheisser schrieb:

    Könntest du mir das genauer erkläreen?

    Ich habe ehrlich gesagt wirklich nicht Lust, das erneut zu diskutieren. Aber wenn du die Forensuche einsetzt, kannst du einige Threads dazu finden.

    In Kürze:

    • Fehlende Typsicherheit durch variable Funktionsargumente, keine Prüfung, ob %-Formatflags auf den richtigen Typen angewandt werden
    • Keine Unterstützung für Non-PODS (wie hier für std::string )
    • manuelle Speicherverwaltung und damit Gefahr von Pufferüberläufen

    Es ist ja nicht so, als wären die C++-Streams das einzig Wahre, die C-Funktionen haben durchaus ihre Berechtigung. Aber man sollte wirklich genau wissen, was man tut, wenn man sie anwendet. Und für sehr viele Fälle finde ich einen einfachen std::stringstream geeigneter.



  • LordJaxom schrieb:

    pumuckl schrieb:

    std::string error = static_cast<std::stringstream&>(std::stringstream() << "Error " << moep << ' ' << var << '\n').str();
    

    Ich möchte wetten, das hast Du nicht ausprobiert. 😉

    Spielt keine Rolle, weil es geht! :p

    @Nexus: Danke ich such mal.h



  • LordJaxom schrieb:

    pumuckl schrieb:

    std::string error = static_cast<std::stringstream&>(std::stringstream() << "Error " << moep << ' ' << var << '\n').str();
    

    Ich möchte wetten, das hast Du nicht ausprobiert. 😉

    Doch. vc7 schluckts, und ich wüsste auch nicht was daran böse sein soll.



  • Hossenscheisser schrieb:

    Spielt keine Rolle, weil es geht! :p

    Mach ich auch immer so. Code muss nur funktionieren... 🤡



  • Nexus schrieb:

    Hossenscheisser schrieb:

    Spielt keine Rolle, weil es geht! :p

    Mach ich auch immer so. Code muss nur funktionieren... 🤡

    Was stimmt daran denn nicht!? Und duchs pure betrachten finde ich auch keine Fehler!



  • pumuckl schrieb:

    audacia schrieb:

    @pumuckl: das ist kein Einzeiler 😉

    std::string error = static_cast<std::stringstream&>(std::stringstream() << "Error " << moep << ' ' << var << '\n').str();
    

    🙄

    Die Sache hat leider einen kleinen Haken. Benutzerdefinierte Typen funktionieren hier nicht als erstes Argument, da solche freien operator<<-Funktion den Stream als Referenz annehmen und std::stringstream() aber ein temporäres Objekt ist.

    Unter Verwendung des kleinen a2str-Hilfsmittels, welches ich im anderen Thread gezeigt hatte, tritt dieses Problem nicht auf. Es ist außerdem auch kürzer:

    std::string error = a2str() << "Error " << moep << ' ' << var << '\n';
    

    Gruß,
    SP


Anmelden zum Antworten