Problem bei meiner String-replace Funktion



  • Hi,
    ich wollte mir eine kleine Str-replace Funktion zusammenbasteln (ala str_replace in PHP).
    Funktioniert soweit auch alles eigentlich, nur wenn der Platzhalter am Ende des Suchstrings steht funktionierts nichtmehr 😞

    char *parse_template(const char *str, const char *search, const char *replace)
    {
    	char *pos1, *pos2, *buff;
    	char dbgstr[50];
    	unsigned short szbuff=0;
    
    	pos1 = strstr(str, search);
    	pos2 = strstr(pos1, " ");
    
    	szbuff += ( strlen(str) - strlen(pos1) );
    	szbuff += strlen(replace);
    
    	if(NULL != pos2)
    		szbuff += ( strlen(str) - strlen(pos2) );
    
    	buff = (char *)malloc((szbuff + 1) * sizeof(char));
    	if(NULL == buff)
    		return NULL;
    
    	strncpy(buff, str, (strlen(str) - strlen(pos1)));
    	strncat(buff, replace, strlen(replace));
    	if(NULL != pos2)
    			strncat(buff, pos2, strlen(pos2));
    
    	#ifdef DEBUG
    		sprintf(dbgstr, "Tpl-Parser: buffsize: %d actual size: %d", szbuff, strlen(buff));
    		debug_msg(dbgstr, __LINE__, NLERR_DEBUG);
    	#endif
    
    	return buff;
    }
    

    so einmal verwendet so:

    tpl = parse_template("Das ist der %repl von dem!", "%repl", "REPLACE");	
    printf("Template: %s\n", tpl);
    

    Ausgabe stimmt dann:

    [DEBUG]: Tpl-Parser: buffsize: 36 actual size: 28 [LINE]: 188
    Template: Das ist der REPLACE von dem!
    

    und jetzt %repl am Stringende:

    tpl = parse_template("Das ist der %repl", "%repl", "REPLACE");	
    printf("Template: %s\n", tpl);
    

    und gibt dann aus:

    [DEBUG]: Tpl-Parser: buffsize: 19 actual size: 20 [LINE]: 188
    Template: Das ist der 2REPLACE
    

    ich denk dass das irgendwie auch damit zusammenhängt, dass "buffsize" und "actual size" falsche Werte haben.
    Kann mir da mal jemand weiterhelfen ... 😞



  • helloJoe schrieb:

    [cpp]
    char *parse_template(const char *str, const char *search, const char *replace)
    {
    char *pos1, *pos2, *buff;
    char dbgstr[50];
    unsigned short szbuff=0;

    pos1 = strstr(str, search);
    pos2 = strstr(pos1, " ");

    szbuff += ( strlen(str) - strlen(pos1) );
    szbuff += strlen(replace);

    if(NULL != pos2)
    szbuff += ( strlen(str) - strlen(pos2) );

    Das ist die Länge des Gesamtstrings bis das erste Leerzeichen nach dem gesuchten String (darf der keine Leerzeichen enthalten?). Du willst hier, denke ich, eher die Länge des Strings nach diesem Leerzeichen. Das ist aber nur strlen(pos2). -- Allerdings verstehe ich so deine Debug-Ausgabe nicht. szbuf und strlen(buf) sollten sich meiner Ansicht nach nicht unterscheiden (oder höchstens um eins, weil Du explizit beim malloc das +1 dazuschreibst ...).

    buff = (char *)malloc((szbuff + 1) * sizeof(char));

    buff = malloc(szbuff + 1);
    reicht.

    if(NULL == buff)
    return NULL;

    strncpy(buff, str, (strlen(str) - strlen(pos1)));
    strncat(buff, replace, strlen(replace));

    Das kann schiefgehen, wenn Du nicht an der passendes Stelle ein Stringterminierungszeichen ('\0') eingefüht hast. Außerdem brechnest Du strlen(str)-strlen(pos1) (ich nenne das len) nicht zum ersten mal. Und strncat ließe sich bequem als strcpy(buf+len, replace) schreiben. Scheint mir eingängiger.


Anmelden zum Antworten