Allgemeine Frage, betreffs "printf" und "cout"



  • Konrad Rudolph schrieb:

    thordk schrieb:

    das einzige, was mich an streams stört ist... naja, dass es streams sind :p die vorteile sind unbestritten, aber diese ganzen << und >> im code, die keine bit-shifts, sondern streams sind, find ich eklig 😉

    Ich erwarte immer noch, dass jemand einen besseren Vorschlag macht. '+=' finde ich hierbei z.b. extrem schlecht geeignet.

    cout.append("foobar").setw(5).setprecision(2).append(3.14f).endl().append("noch ne zeile");
    


  • Ja, das wäre eine Möglichkeit - aber anstelle von append() würde ich eher 'print()' (bzw. für Eingaben 'read()') verwenden. Allerdings hat sowas den Nachteil, daß es nicht erweiterbar ist (operator<< kannst du global definieren, um eigene Typen per append() bzw. print() ausgeben zu können, mußt du die Klasse basic_ostream umbauen).



  • thordk schrieb:

    Konrad Rudolph schrieb:

    thordk schrieb:

    das einzige, was mich an streams stört ist... naja, dass es streams sind :p die vorteile sind unbestritten, aber diese ganzen << und >> im code, die keine bit-shifts, sondern streams sind, find ich eklig 😉

    Ich erwarte immer noch, dass jemand einen besseren Vorschlag macht. '+=' finde ich hierbei z.b. extrem schlecht geeignet.

    cout.append("foobar").setw(5).setprecision(2).append(3.14f).endl().append("noch ne zeile");
    

    Java lässt grüßen. Genau für solche Zwecke (Verkettung vieler Operationen) sind Operatoren nunmal ideal geeignet. Ich finde Deinen Code wesentlich unübersichtlicher als die Verwendung eines arbiträren Operators. Von den Problemen, die CStoll aufgezeigt hat, ganz zu schweigen.

    Ich sollte hier vielleicht darauf hinweisen, dass ich die Lösung über '<<' auch nicht ideal finde. Generell bevorzuge ich z.B. die Boost-format-Variante. Es stellt sich eben die Frage, ob man durch die Syntax überhaupt klarmachen muss, dass man auf einen Stream zugreift. Aber auch die Boost-format-Variante überlädt einen Operator und ihm eine (nicht ganz) neue Semantik, zumindest im Kontext von C++ (Perl z.B. kennt etwas ähnliches).

    Generell finde ich es aber *nicht* schlimm, Operatoren eine neue Semantik zu verpassen, wie es hier geschehen ist. Das Argument, dass man hier eine Bit-Shift-Operation erwartet, kann ich nicht nachvollziehen. Solange man ein wenig Vorsicht walten lässt und Operatoren nicht offensichtlich sinnlose oder widersprüchliche Semantiken verpasst, ist das überhaupt kein Problem.



  • Konrad Rudolph schrieb:

    Ich erwarte immer noch, dass jemand einen besseren Vorschlag macht. '+=' finde ich hierbei z.b. extrem schlecht geeignet.

    finde ich auch: man sollte dafür ein neues token erfinden, da << und >> ja schon anderweitig belegt sind, und zu verwechselungen führen können.
    -> ist leider auch schon vergeben.
    vielleicht >>> und <<< ?
    das scheint mir aber auch nicht optimal, die cout/cin zeilen würden dadurch noch länglicher werden.
    🙂

    Konrad Rudolph schrieb:

    Generell bevorzuge ich z.B. die Boost-format-Variante.

    also doch 'printf' 😉



  • pale dog schrieb:

    Konrad Rudolph schrieb:

    Generell bevorzuge ich z.B. die Boost-format-Variante.

    also doch 'printf' 😉

    Boost-Format verwendet kein printf! 🙂



  • pale dog schrieb:

    Konrad Rudolph schrieb:

    Ich erwarte immer noch, dass jemand einen besseren Vorschlag macht. '+=' finde ich hierbei z.b. extrem schlecht geeignet.

    finde ich auch: man sollte dafür ein neues token erfinden, da << und >> ja schon anderweitig belegt sind, und zu verwechselungen führen können.
    -> ist leider auch schon vergeben.
    vielleicht >>> und <<< ?
    das scheint mir aber auch nicht optimal, die cout/cin zeilen würden dadurch noch länglicher werden.
    🙂

    Dagegen sprechen allerdings die natürlichen Beschränkungen der Sprache - du kannst bestehende Operatoren für eigene Typen überladen, aber du kannst weder neue Operatoren definieren noch die Rangfolge etc. der Operatoren beeinflussen. Das heißt, wenn du einen Stream-Operator auswählen willst, bist du auf das vorhandene Sortiment beschränkt.



  • David_pb schrieb:

    Boost-Format verwendet kein printf! 🙂

    aber 'ne ähnliche syntax wie die printf formatstrings 😃



  • Naja, "ähnlich". Aber dafür Typensicher! 🙂



  • CStoll schrieb:

    pale dog schrieb:

    Konrad Rudolph schrieb:

    Ich erwarte immer noch, dass jemand einen besseren Vorschlag macht. '+=' finde ich hierbei z.b. extrem schlecht geeignet.

    finde ich auch: man sollte dafür ein neues token erfinden, da << und >> ja schon anderweitig belegt sind, und zu verwechselungen führen können.
    -> ist leider auch schon vergeben.
    vielleicht >>> und <<< ?
    das scheint mir aber auch nicht optimal, die cout/cin zeilen würden dadurch noch länglicher werden.
    🙂

    Dagegen sprechen allerdings die natürlichen Beschränkungen der Sprache - du kannst bestehende Operatoren für eigene Typen überladen, aber du kannst weder neue Operatoren definieren noch die Rangfolge etc. der Operatoren beeinflussen. Das heißt, wenn du einen Stream-Operator auswählen willst, bist du auf das vorhandene Sortiment beschränkt.

    ach, mist, das hab' ich übersehen.
    also: sprache erweitern, so dass selbstdefinierte operatoren möglich sind 👍



  • pale dog schrieb:

    ach, mist, das hab' ich übersehen.
    also: sprache erweitern, so dass selbstdefinierte operatoren möglich sind 👍

    Vollkommen überflüssig. Wie ich bereits sagte: Es spricht IMHO nichts dagegen (einige Sorgfalt vorausgesetzt), bestehende Operatoren mit einer neuen Semantik zu belegen.

    /EDIT: Und zu Boost.Format: Finde ich zwar gut, die 'printf'-ähnliche Format-Syntax finde ich hingegen furchtbar. Die .NET-Lösung ist hier z.B. angenehmer.



  • Konrad Rudolph schrieb:

    pale dog schrieb:

    ach, mist, das hab' ich übersehen.
    also: sprache erweitern, so dass selbstdefinierte operatoren möglich sind 👍

    Vollkommen überflüssig.

    an C++ wird doch sowieso ständig herumgeschraubt. wer weiss, vielleicht kommt sowas mal.

    Konrad Rudolph schrieb:

    /EDIT: Und zu Boost.Format: Finde ich zwar gut, die 'printf'-ähnliche Format-Syntax finde ich hingegen furchtbar. Die .NET-Lösung ist hier z.B. angenehmer.

    printf-syntax ist doch gar nicht so kryptisch. schau dir mal 'regular expressions' an, dann weisst du, was schlimm ist 😉

    btw: je mächtiger/universeller etwas ist, desto komplizierter wird es. das scheint ein naturgesetz zu sein. auf programmiersprachen-kram trifft es jedenfalls zu...
    🙂



  • pale dog schrieb:

    Konrad Rudolph schrieb:

    pale dog schrieb:

    ach, mist, das hab' ich übersehen.
    also: sprache erweitern, so dass selbstdefinierte operatoren möglich sind 👍

    Vollkommen überflüssig.

    an C++ wird doch sowieso ständig herumgeschraubt. wer weiss, vielleicht kommt sowas mal.

    Aufgrund der damit verbundenen technischen Probleme relativ unwahrscheinlich.

    printf-syntax ist doch gar nicht so kryptisch. schau dir mal 'regular expressions' an, dann weisst du, was schlimm ist 😉

    Also, in aller Bescheidenheit möchte ich mal behaupten, dass ich reguläre Ausdrücke flüssig lesen und schreiben kann, und zwar wahrscheinlich besser als die meisten Perl-Programmierer. Aber Du vergleichst hier Äpfel mit Birnen. Reguläre Ausdrücke sind eine eigenständige, extrem mächtige Sprache. Diese Mächtigkeit ist bei der Stringformatierung überhaupt nicht nötig. Abgesehen davon sind die .NET-Formatstrings wesentlich mächtiger als die von C-'printf' und sie sind trotzdem lesbarer.

    btw: je mächtiger/universeller etwas ist, desto komplizierter wird es. das scheint ein naturgesetz zu sein.

    Das scheint falsch zu sein, wenn man sich die Physik anschaut. 😉 Immerhin lassen sich sehr allgemeine Zusammenhänge in sehr einfachen Formeln ausdrücken. Aber das gehört nicht hierher.



  • Konrad Rudolph schrieb:

    Java lässt grüßen.

    merkt man, oder? *G bin beruflich bedingt wieder auf java umgestiegen. nach paar jahren c++ wars ne recht harte umgewöhnung, aber man merkt doch, dass bei java wert auf eine sehr saubere und klare strukturierung gelegt wurde. kann c++ nur gut tun 😉



  • pale dog schrieb:

    ....
    - cout macht falsche ausgaben, wenn variablen als 'volatile' deklariert sind.
    - bei cout muss man manchmal 'endl' o.ä. dranhängen, sonst wird nix ausgegeben.
    🙂
    aber im grunde genommen ist es egal, welches man benutzt.

    Ersteres nur, wenn man seine Compiler-Warnungen ignoriert und Zweiteres leuchtet mir gar nicht ein: Warum sollten printf() und cout unterschiedlichen flushing-Strategien haben (und warum soillte ein "schnelles flush" automatisch besser sein) ?
    Die "einfachere Benutzung für bestimmte Formatierungen" (die ich auch so sehe) muss man eben gegen die Typsicherheit (inkl. Readoverflows) und die (IMO) weniger kryptischen Formatierungsmöglichkeiten abwägen....

    Gruß,

    Simon2.



  • thordk schrieb:

    ...

    cout.append("foobar").setw(5).setprecision(2).append(3.14f).endl().append("noch ne zeile");
    

    Mach das mal mit einem 5mal so langen Ausdruck !
    Die Operatorsyntax (sei es nun <<>> oder was auch immer) hat nunmal den Vorteil, eine Quelltextstrukturierung whitespaces zu erlauben, was mit "." nicht geht.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    ie Operatorsyntax (sei es nun <<>> oder was auch immer) hat nunmal den Vorteil, eine Quelltextstrukturierung whitespaces zu erlauben, was mit "." nicht geht.

    Doch

    ich. kann().
         meine()   .c_operatoren() -> formatieren, wie( ich ).lustig . bin;
    


  • Konrad Rudolph schrieb:

    Simon2 schrieb:

    ie Operatorsyntax (sei es nun <<>> oder was auch immer) hat nunmal den Vorteil, eine Quelltextstrukturierung whitespaces zu erlauben, was mit "." nicht geht.

    Doch

    ich. kann().
         meine()   .c_operatoren() -> formatieren, wie( ich ).lustig . bin;
    

    😮 😮 😮 😮
    Also das war mir neu !
    OK, ich ziehe meinen Einwand zurück .... und finde immer noch die Operatoren "hübscher".

    Gruß,

    Simon2.



  • pale dog schrieb:

    an C++ wird doch sowieso ständig herumgeschraubt. wer weiss, vielleicht kommt sowas mal.

    Ich frage mich, woher dieses Gerücht kommt. C++ ist seit 1998 standardisiert und da wird nicht ständig herumgeschraubt. Die nächste Version ist 2009 zu erwarten. Das sind 11 Jahre, wo sich in C++ nichts geändert hat. Vergleiche das mal mit anderen Sprachen.

    Um hier nicht den falschen Eindruck zu hinterlassen: das ist einer der großen Vorteile von C++. Ich muss meine Programme nicht ständig neuen Versionen anpassen.

    Und noch was: So sieht das schon lesbarer aus:

    cout.append("foobar")
        .setw(5)
        .setprecision(2)    // jetzt passt hier sogar ein Kommentar rein
        .append(3.14f)
        .endl()
        .append("noch ne zeile");
    

    Und das append (oder print) könnte natürlich ein Template sein, welches operator<< aufruft und dadurch erweiterbar wird. Wobei ich die vorhandene Schreibweise bevorzuge. Aber die Formatierung ist mit iostreams problematischer, als mit printf. Deswegen hat man boost.format geschaffen, welches bezüglich Sicherheit klar an printf vorbeizieht.

    Ansonsten kann ich mich dem nur anschliessen, daß auch ich schon einige Programme gesehen habe, die an fehlerhaften Formatstrings in printf gescheitert sind. Daher verwende ich kein printf.



  • tntnet schrieb:

    pale dog schrieb:

    an C++ wird doch sowieso ständig herumgeschraubt. wer weiss, vielleicht kommt sowas mal.

    Ich frage mich, woher dieses Gerücht kommt....

    Wahrscheinlich mit Java verwechselt - kann ja mal passieren ... 😉

    tntnet schrieb:

    ...Aber die Formatierung ist mit iostreams problematischer, als mit printf....

    Magst Du mal anführen, wieso ?
    Was mich bei den Streams stört, ist, dass sie "die Formatierer vergessen" ... oder kann man cout irgendwie "einmalig um- und später wieder zurückstellen" ?

    Gruß,

    Simon2.



  • MFK schrieb:

    Der Typ mit der Frage schrieb:

    Also ist cout mal abgesehen von der Geschwindigkeit besser als printf?

    Nein. So einfach ist das nicht.

    Wenn du den Thread liest, sollte doch klar werden, dass viel vom Bewertungsmaßstab und von persönlichen Vorlieben abhängt. Was "besser" ist, kannst du nur für dich selbst definieren. Je nachdem, was dir wichtig ist, könnte auch boost::format "besser" sein.

    Ja, mann kann für die Ausgaben auch Assembler benutzen, oder mit einem Edding sein C++ Hello World auf den Monitor schreiben. 🙂


Anmelden zum Antworten