sprintf kapselung



  • 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



  • Shade Of Mine schrieb:

    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??    
        // warum nicht ?
    
        va_start (ap, fmtspec);
        va_end (ap);
        char * buf = NULL;
        //das strlen() ist mies. warum nicht gleich strlen()+50% oder uU 100% ?
       // ist nur die "erste" Grosse, Bewertung
        for (unsigned int initLen = strlen (fmtspec) + 1;;initLen = initLen * 2 + 1) {   //warum überall diese +1 ? das verwirrt mich...
      // kann initLen * 2 sein
            delete [] buf;
            buf = new char [initLen + 1];
            //warum nicht realloc?
           // wir sprechen ueber C++ oder ?
            buf [initLen] = 0; //warum?
            // das ist mein Fehler kann Man dass weg lassen :)
            unsigned int res = vsnprintf (buf, initLen, fmtspec, ap);
            if (res < initLen) { //was ist wenn res==initLen ? 
            // res ist die Anzhal ohne '\0 denn muss mann 
            // unsigned int res = vsnprintf (buf, initLen + 1, fmtspec, ap);
           // schreiben
                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

    Und dass ist nur ein 5-sec Beispiel, es ist gar nicht ideal



  • Shade Of Mine schrieb:

    itman schrieb:

    Das folgender ist besser, keine "memory

    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

    Und gar keine einzige Ausnahme!!!
    z.B

    sprintf(buf, "%f", val)
    

    wass ist buf groesse? du kannst die maximale groesse berechnen, aber wenn du damit ein Feheler machst ist der Code kaput - buffer overflow.


Anmelden zum Antworten