sprintf kapselung



  • ne stlport geht au ned (hab keine exceptions)
    ich will nur mit ner eigenen funktion sprintf parameter annehmen und an sprintf weitergeben

    sind 5 zeilen code... aber ich find sie nich mehr... vielleicht sollt ich nochmal suchen... geht wohl schneller



  • Braucht STLPort denn Exceptions? Ich bilde mir ein, dass dies nicht nötig ist...

    Naja, du kannst sowieso keine Parameter an sprintf weitergeben. Du kannst dur vsprintf aufrufen...



  • Ich kenn mich da nicht so aus und bin mir nicht so sicher, ob das jetzt zum Thema ist, aber meinst du vielleicht:

    void dumdidum(char* msg, ...)
    {
    va_list args;
    va_start(args,msg);
    char szBuf[1024];
    vsprintf(szBuf,msg,args);
    }
    

    szBuf enthält dann den formatierten String.



  • vsprint und printf sind unsicher!
    es ist immer besser snprintf und vsnprint zu benutzen!



  • @itman is kein ansi



  • *****



  • itman schrieb:

    vsprint und printf sind unsicher!
    es ist immer besser snprintf und vsnprint zu benutzen!

    Blödsinn:

    void something(char const* str)
    {
      size_t len=strlen(str);
      char* buffer=new char[4+len+1];
    
      for(int i=0; i<10; ++i)
      {
        sprintf(buffer, "%d. %s", i+1, str);
        someotherthing(str);
      }
    }
    

    Wo brauche ich da bitte snprintf? sprintf tut es genauso, nur besser.



  • @itman is kein ansi

    aber Posix oder Unix98 compatible. Und WinXXX compatibel dabei.



  • [quote]
    Wo brauche ich da bitte snprintf? sprintf tut es genauso, nur besser.
    [quote]
    "buffer overflow" zu vermeiden.



  • itman schrieb:

    und hier ist ein arbeitender Beispiel:

    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <stdarg.h>
    
    using namespace std;
    
    string
    Format (const char * fmtspec, ...)
    {
        va_list     ap;
    
        va_start (ap, fmtspec);
        va_end (ap);
        char * buf = NULL;
        for (unsigned int initLen = strlen (fmtspec) + 1;;initLen = initLen * 2 + 1) {
            delete [] buf;
            buf = new char [initLen + 1];
            buf [initLen] = 0;
            unsigned int res = vsnprintf (buf, initLen, fmtspec, ap);
            if (res < initLen) {
                return string (buf);
            }
        }
    }
    
    int
    main (void)
    {
        string s = Format ("Big test %d %4.2f", 23, 44.533);
        cout << s<<endl;
    }
    


  • Sovok schrieb:

    @itman is kein ansi

    Wäre mir neu, dass snprintf kein Standard ist...



  • itman schrieb:

    Wo brauche ich da bitte snprintf? sprintf tut es genauso, nur besser.

    "buffer overflow" zu vermeiden.

    wo ist da ein potentieller Bufferoverflow?

    Ich muss nur auf Usereingaben acht geben - beim rest kenne ich die größen meiner Strings...



  • kein Standard ist

    kein ANSI 89 Standard aber ist C99 standard.



  • @itman:
    ich kapier deinen Code zwar nicht, aber er leaked speicher. Insofern würde ich das funktionierend lieber in Hochkommas setzen 😉



  • ich hab die funktion jedenfalls ned



  • itman schrieb:

    kein Standard ist

    kein ANSI 89 Standard aber ist C99 standard.

    Wenn du mich zitierst, dann tu es gefälligst ordentlich! 😡



  • Sovok schrieb:

    ich hab die funktion jedenfalls ned

    Dann hast du nen alten Compiler.

    Jetzt wirds problematisch. Du könntest zB die einzelnen größen händisch berechnen 😉 aber das ist wohl nicht so ganz das wahre...

    Ich würde es einfach lassen... die Funktion Format (oder wie auch immer) soll die benötigte größe als Param übergeben bekommen - das ist sicher genug. denn dann liegt es am Programmierer das Ding sicher zu machen (und es ist nicht so arsch lahm wie eine for-schleife mit dauerndem realloc)



  • Shade Of Mine schrieb:

    @itman:
    ich kapier deinen Code zwar nicht, aber er leaked speicher. Insofern würde ich das funktionierend lieber in Hochkommas setzen 😉

    Das folgender ist besser, keine "memory leaks". Der Code ist einfach.
    vsnprintf gibt die char-Anzahl zuerueck. wenn diese Anzahl = Speicher kapazitet denn
    ist es moeglich dass kapazitet ist zu wenig ist. Denn brauchen wir mehr Speicher zu reservieren.

    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <stdarg.h>
    
    using namespace std;
    
    string
    Format (const char * fmtspec, ...)
    {
        va_list     ap;
        string      s;
    
        va_start (ap, fmtspec);
        char * buf = NULL;
        for (unsigned int initLen = strlen (fmtspec) + 1;;initLen = initLen * 2 + 1) {
            delete [] buf;
            buf = new char [initLen + 1];
            buf [initLen] = 0;
            unsigned int res = vsnprintf (buf, initLen, fmtspec, ap);
             if (res < initLen) {
                s = buf;
                delete [] buf;
                va_end (ap);
                return s;
            }
        }
    }
    


  • Shade Of Mine schrieb:

    Sovok schrieb:

    ich hab die funktion jedenfalls ned

    Ich würde es einfach lassen... die Funktion Format (oder wie auch immer) soll die benötigte größe als Param übergeben bekommen - das ist sicher genug. denn dann liegt es am Programmierer das Ding sicher zu machen (und es ist nicht so ***** lahm wie eine for-schleife mit dauerndem realloc)

    Die benoetigte grosse kann Man im vorauss nicht immer weissen 🙂



  • itman schrieb:

    Das folgender ist besser, keine "memory leaks".

    dafür immer noch mies...

    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <stdarg.h>
    
    using namespace std;
    
    string
    Format (const char * fmtspec, ...)
    {
        va_list     ap;
        string      s; //warum hier definieren??
    
        va_start (ap, fmtspec);
        va_end (ap);
        char * buf = NULL;
        //das strlen() ist mies. warum nicht gleich strlen()+50% oder uU 100% ?
        for (unsigned int initLen = strlen (fmtspec) + 1;;initLen = initLen * 2 + 1) {   //warum überall diese +1 ? das verwirrt mich...
            delete [] buf;
            buf = new char [initLen + 1];
            //warum nicht realloc?
            buf [initLen] = 0; //warum?
            unsigned int res = vsnprintf (buf, initLen, fmtspec, ap);
            if (res < initLen) { //was ist wenn res==initLen ?
                s = buf;
                delete [] buf;
                return s;
            }
        }
    }
    

    Die benoetigte grosse kann Man im vorauss nicht immer weissen

    Ich weiss sie schon.
    Ausnahme: Input von extern.
    hier tut mir ein strlen() aber nicht weh... Und schon kenn ich die größe wieder...

    ah, das ist auch so schön effizient


Anmelden zum Antworten