Strings formattieren wie in printf()....



  • Hi, ich moechte eine Funktion schreiben, die Parameter auf die selbe Weise annimmt wie z. B. printf()... z. B.

    foo("string mit %d Integer", 1);
    

    ich hab ein wenig gegoogelt und dabei folgendes gefunden:

    #include <stdarg.h>
    
    void log_warning(const char *fmt, ...)
    {
    	va_list ap;
    
    	fprintf(stderr, "WARNING: ");
    	va_start(ap, fmt);
    	vfprintf(stderr, fmt, ap);
    	va_end(ap);
    	fprintf(stderr, "\n");
    }
    

    ist aber reines C schaetz ich mal.... deshalb:
    a) gibts 'nen C++ - Weg das zu machen?
    b) wie komm ich dann an den "fertigen" (zusammengestzten) String?

    P. S. nein, stringstreams helfen mir nicht unbedingt weiter, ich moecht das wirklich so machen wie z. B. auch printf()



  • wenn du nur strings formatieren willst, nimm doch einfach sprintf() oder versteh ich da was falsch?



  • Xjoni schrieb:

    wenn du nur strings formatieren willst, nimm doch einfach sprintf() oder versteh ich da was falsch?

    Ich glaub eher er will wie bei printf() eine variable Anzahl an Parametern übergeben?

    Das geht imho immer noch mit diesen Makros.

    MfG SideWinder





  • Thx fuer die Antworten... aber gibts nicht eine "einfachere" Loesung, so dass ich nicht auf externe Libs zugreifen muss?

    SideWinder schrieb:

    Xjoni schrieb:

    wenn du nur strings formatieren willst, nimm doch einfach sprintf() oder versteh ich da was falsch?

    Ich glaub eher er will wie bei printf() eine variable Anzahl an Parametern übergeben?

    stimmt genau.... allerdings immer Strings, in denen andere Variablenwerte "eingebettet" sind... wie bei printf(), sprintf() usw....



  • Die C++-Standardbibliothek ist nunmal recht eingeschränkt...
    Boost muss größtenteils nicht kompiliert werden (d.h. #include reicht), folgt den gleichen Konventionen wie die Standardbibliothek und vieles aus Boost wird auch in die Standardbibliothek übernommen werden (ok, format gehört wohl nicht dazu). Boost ist imho definitiv ein Anfreunden wert.



  • Wenn du den Code wie folgt abänderst kannst du das Ergebnis weiterverwenden, dein formatierter String ist in antwort.
    Ist allerdings tiefstes C. 😃

    #include <stdarg.h> 
    
    void log_warning(char* antwort, const char *fmt, ...) 
    { 
        va_list ap; 
        char *buffer=antwort+9; // buffer wird auf die \0 von Warning positioniert.
        strcpy(antwort,"WARNING: "); 
        va_start(ap, fmt); 
        vsprintf(buffer, fmt, ap); 
        va_end(ap); 
        strcat(antwort,"\n"); 
    }
    


  • das problem mit ... ist, dass du von irgenwoher wissen musst, welche Typen denn so übergeben werden un da deine Funktion nicht alle Typen kennen kann (ich kann ja jederzeit neue erstellen) ist ... in einer oo-Spraceh recht unpassend.

    Ist es nicht möglich mit ein wenig copy und past eine mehrfach überladene template-Funktion zu verwenden?

    Ansonsten verwende doch wie boost::format den Trick mit dem überladenen Operator.



  • ne, danke... wenn man Strings, Floats und Ints ausgeben kann reicht das voellig... wer dann doch lieber bei der "abgrundtiefstes C" - Variante bleiben 😉

    Hat den Vorteil dass der Aufrufsyntax sofort verstaendlich ist und die Benutzer der Funktion keine zusaetzlichen includes (wie z. B. bei boost der Fall waere) brauchen 🙂



  • Das ist der Vorteil von C man weis was man tut, und sieht wie es passiert.



  • Dass der Code Bufferoverflows geradezu einlädt, weißt du aber? 😉



  • tag schrieb:

    Dass der Code Bufferoverflows geradezu einlädt, weißt du aber? 😉

    Zeig ne alternative die sicher ist.

    Solange answer (auf jedenfall >9) ausreichend vom rufenden dimensioniert ist, sollte es problemlos sein.

    Und die Standardprobleme von *printf sind ja bekannt



  • PAD schrieb:

    Und die Standardprobleme von *printf sind ja bekannt

    Erzähl mal, bitte.



  • Das Argument mit den weiteren Includes verstehe ich nicht. Die kommen doch in deinen Header, da er Sie benötigt. Ich muss weiterhin nur deine Datei einbinden.



  • Daniel E. schrieb:

    PAD schrieb:

    Und die Standardprobleme von *printf sind ja bekannt

    Erzähl mal, bitte.

    Da du einen Formatierstring angibst, und dahinter eine variable argumentenliste, musst du als Programmierer sicherstellen, das die argumente und die Element im formatierstring matchen.

    Schreibst du z.B. %f werden 4 Bytes vom Stack ausgewertet, schribst du %lf werden 8 Bytes vom Stack ausgewertet, vertust du dich kommt der Stack durcheinander mit nicht vorhersehbaren folgen. wählst du den Asugabebuffer bei den sprintf zu klein erzeugst du fantastische Buffer overflows, analog oder noch schlimmer gilt dies für die scanf Familie. Und keine Compiler kann oder will prüfen ob das passt oder nicht.



  • PAD schrieb:

    Da du einen Formatierstring angibst, und dahinter eine variable argumentenliste, musst du als Programmierer sicherstellen, das die argumente und die Element im formatierstring matchen.

    Und ich dachte schon, es sei was ernstes.

    wählst du den Asugabebuffer bei den sprintf zu klein erzeugst du fantastische Buffer overflows,

    snprintf.



  • Helium schrieb:

    Das Argument mit den weiteren Includes verstehe ich nicht. Die kommen doch in deinen Header, da er Sie benötigt. Ich muss weiterhin nur deine Datei einbinden.

    ok, da hab ich nicht dran gedacht... aber jeder Benutzer der Funktion muss die (IMO nicht auf den ersten Blick verstaendliche) Syntax kennen....



  • Daniel E. schrieb:

    snprintf.

    Das ist Schummeln, das ist kein C++98. (Soweit ich das aus der MSDN sehe.)



  • operator void schrieb:

    Daniel E. schrieb:

    snprintf.

    Das ist Schummeln, das ist kein C++98. (Soweit ich das aus der MSDN sehe.)

    Jup, die letzte Seite ging es allerdings von »tiefem« über »abgrundtiefstem« bis einfach nur C.



  • aber jeder Benutzer der Funktion muss die (IMO nicht auf den ersten Blick verstaendliche) Syntax kennen....

    Ich sehe da jetzt nicht das Problem. Das ist grundsätzlich bei allen Funktionen so, nicht nur bei dieser einen.


Anmelden zum Antworten