2016-07-30 43 views
-3

Was ist falsch mit der Funktion. Wie kommt es, dass nichts ausgedruckt wird?So verwenden Sie sprintf mit Zeichenzeiger in C

char * CombineStr(char * str1, char * str2) 
{ 
    char strOut[256]; 
    sprintf(strOut, “%s%s”, str1, str2); 
    return strOut; 
} 
+4

UB? Sie ordnen strout im Stapel zu und geben einen Zeiger auf eine Position zurück, die bei Rückgabe der Funktion "freigegeben" wird. – Amadeus

+0

@Amadeus Einheimische sind im Stapel nicht im Heap zugeordnet. – Sergio

+0

@Serhio danke richtig gedacht, falsch schreiben – Amadeus

Antwort

0

Wechseln Sie zu static char strOut[256];. Es ist keine sehr gute Lösung, wird aber funktionieren.

+1

Nachteile eines solchen Ansatzes sollte IMO beschrieben werden. – Sergio

+0

@Serhio Der Nachteil ist, dass der statische Puffer nur einer ist und wenn jemand 'CombineStr' zum Beispiel in' sprintf' als 2 oder mehr Parameter (2+ Aufrufe) verwendet, wird das Ergebnis falsch sein. Aus diesem Grund ist meine Lösung einfach und funktioniert aber nicht in allen Fällen. – i486

2

Sie sollten Umfang (Speicherdauer Ihres variabel) kümmern: entweder deklarieren zurückgegebenen Variablen als statisch, oder sie verteilen sich dynamisch auf dem Heap, mit malloc und free ing der zugewiesenen Speicher wies von strOut, einmal nicht benötigt nicht mehr. Sie sollten einfache Anführungszeichen im Format Ihres zweiten Arguments sprintf verwenden. Sie sollten auf Überlauf achten.
entweder:

char * CombineStr(char * str1, char * str2) 
{ 
    static char strOut[256];     //scope! 
    if((strlen(str1) + strlen(str2)) < 256) 
     sprintf(strOut, "%s%s", str1, str2); //plain quotes! 
    return strOut; 
} 

oder:

char * CombineStr(char * str1, char * str2) 
{ 
    char strOut = malloc(strlen(str1) + strlen(str2) + 1);    
    if(strOut != NULL) 
     sprintf(strOut, "%s%s", str1, str2); //plain quotes! 
    return strOut; 
} 

Für weitere Lesung, nehmen Sie bitte einen Blick auf Beiträge folgende SO: 1, 2.

+2

Hack mit 'static' funktioniert nicht gut, wenn der Benutzer beschließt,' CombineStr() 'einige Male aufzurufen und die zwischengespeicherten Ergebnisse später zu verwenden. Und was ist mit Multithreading-Umgebung? – Sergio

+0

Danke @Serhio. Hinzugefügtes Beispiel mit dynamischer Zuweisung. – user3078414

1

Eine weitere übliche Lösung ist der Anrufer bereitzustellen

char * CombineStr(const char * str1, 
        const char * str2, 
        char * strOut, 
        size_t outlen) 
{ 
    size_t len = snprintf(strOut, outlen, "%s%s", str1, str2); 
    if (len < outlen) 
    { 
     return strOut; 
    } 
    return NULL; 
} 

Hinweis den Schalter von sprintf zu snprintf verhindern Pufferüberlauf des Ausgangspuffer der verkettete Zeichenkette, die die Länge des Puffers überschreiten zu lassen. Dadurch können wir den Überlauf abfangen und ein ungültiges Ergebnis zurückgeben, damit der Anrufer weiß, dass buffer nicht vertrauenswürdig ist.

Typische Anwendungen würde

char buffer[256]; 
if (CombineStr("I's the b'y that builds the boat", 
       "And I's the b'y that sails her", 
       buffer, 
       sizeof(buffer)) != NULL) 
{ 
    // use buffer 
} 

sein Es sei darauf hingewiesen werden muss, dass snprintf wackelig Unterstützung und kann nicht immer trauen null beendet worden, aber Sie können sicher sein, dass es nicht der Pufferüberlauf hat.