printf conversion-specifier durch I/O-Stream Manipulatoren ersetzen?


  • Mod

    Ist es möglich, folgendes mit cout zu schreiben, und zwar durch entsprechende Manipulatoren:

    printf("%+.4i", 45);
    

    ?
    Und was wäre der direkteste Weg, es über die C++-Streams zu machen?

    Edit: Titel angepasst



  • #include <iostream>
    #include <iomanip>
    using namespace std;
    
    void main()
    {
    	int x = 45;
    	printf("%+.4i\n", x);
    	cout << internal << showpos  << setfill('0') << setw(5) << x << endl;
    }
    

    So etwa ?


  • Mod

    Ich hatte einen starken Denkfehler.

    Ich dachte, der Stream hat standardmäßig std::internal festgelegt. showpos, setw und setfill hatte ich angewandt, aber natürlich ohne das Ergebnis.
    Danke!


  • Mod

    Das vorherige ging ja noch, aber wie sieht es damit aus?

    printf("%6.4i", 45);
    

    Die beiden Leerzeichen können nicht von setw eingefügt werden, da dieses schon die Nullen übernimmt... sieht schlecht aus. Kann printf mehr als die C++-IOStreams?



  • Entweder

    int x = 45;
        cout << "  " << setfill('0') << setw(4) << x << endl;
    

    oder

    cout << form2(6,4) << x << endl;
    

    mit

    struct form2
    {
        form2( int width, int numbersize ) : width_(width), numbersize_(numbersize) {}
        int width_, numbersize_;
    };
    std::ostream& operator<<( std::ostream& out, form2 f )
    {
        if( f.width_ > f.numbersize_ )
            out << std::string( f.width_ - f.numbersize_, ' ' );
        return out << std::setfill('0') << std::setw( f.numbersize_ );
    }
    

    Bem.: es war wohl nicht das Ziel der C++-Stream-Entwickler, genau die printf-Formate zu unterstützen (warum auch 😉 )


  • Mod

    Danke, Werner. Das heißt, man muss selber nachhelfen, aber das ist ja kein Problem ( form2 ist schon nah dran). 👍



  • uU findest du boost::format interessant: http://www.boost.org/doc/libs/1_55_0/libs/format/



  • <a href= schrieb:

    Herb Suter">However, that said, those io manipulators are a real pain to use even for text, and are just about unusable for formatting numbers (I assume you want your dollar amounts to line up on the decimal, have the correct number of significant digits, etc.). [...]
    If you are able to use the Boost libraries, run (don't walk) and use the Boost.Format library instead. It is fully compatible with the standard iostreams, and it gives you all the goodness for easy formatting with printf/Posix formatting string, but without losing any of the power and convenience of iostreams themselves.


  • Mod

    Boost.Format kenne ich längst. Ich will ts_printf zu Ende schreiben, sodass es wie printf funktioniert. Sollte ich als unterliegenden Ausgabe-Helfer Boost.Format nehmen, dann ist das nicht mehr Standard-C++..



  • Arcoth schrieb:

    Boost.Format kenne ich längst. Ich will ts_printf zu Ende schreiben, sodass es wie printf funktioniert.

    Ich wette mit dir, dass sprintf und dann den buffer in die iostreams schreiben schneller ist als die iostream-Manipulatoren.

    Ausserdem musst du vorher alle IO-Stream-Flags löschen, bevor du dein ts_printf anwenden kannst, das wird eine Qual ohne ios_flags_saver.

    Arcoth schrieb:

    Sollte ich als unterliegenden Ausgabe-Helfer Boost.Format nehmen, dann ist das nicht mehr Standard-C++..

    Seit wann ist Boost nicht kompatibel mit Standard-C++?



  • Andrei Alexandrescu hat in seinem Vortrag "Variadic Templates are Funadic" erklärt, wie man ein typsicheres printf() mittels Variadic Templates hinbekommt. Du kannst dir ja mal das Video oder die Slides anschauen...


  • Mod

    Ich will doch eine TMP-Version basteln, die den String zur Compile-Zeit auswertet. Hat das etwas damit zu tun?


Log in to reply