Così al volo non mi pare che ci sia nulla di sbagliato (ripeto, l'ho controllato solo di sfuggita), una considerazione che mi viene subito però è che per velocizzare molto il tuo algoritmo potresti evitare di richiamare strlen ogni volta sulle stringhe che rimangono costanti (come search e replace), e piuttosto mettere questi valori in una variabile. Inoltre non ho ben capito che conti fai qui:
codice:
newText = (char *)realloc(newText, ( strlen(newText)+strlen(search)+strlen(text)-iText-strlen(search) ) * sizeof(char) );
(tra l'altro strlen(search) è aggiunto e sottratto, per cui è assolutamente ininfluente); se ho capito bene come funziona il tuo algoritmo basterebbe
codice:
newText = (char *)realloc(newText, ( strlen(newText)+strlen(replace) ) * sizeof(char) );
.
Inoltre, se ho capito cosa sia iNewText, credo che quella strncat potrebbe essere una strncpy.
Infine, la continua chiamata a realloc potrebbe penalizzare le performance; in alcuni casi potrebbe essere meglio prevedere il caso peggiore e allocare il massimo di memoria che potrebbe essere necessaria, oppure utilizzare un approccio ibrido (allocazione del massimo se è sotto tot KB oppure riallocazione di volta in volta).
Un esempio con questo approccio:
codice:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
char * ReplaceString(const char * Str, const char * Search, const char * Replace)
{
/* Lunghezza della stringa da cercare */
size_t searchLength=strlen(Search);
/* Lunghezza della stringa sostitutiva */
size_t replaceLength=strlen(Replace);
/* Lunghezza della stringa in cui verrà effettuata la ricerca */
size_t strLength=strlen(Str);
/* Puntatore alla nuova stringa da restituire */
char * ret;
/* Puntatore al carattere di Str attualmente letto */
const char * readPtr;
/* Puntatore al carattere di ret attualmente scritto */
char * writePtr;
/* Dimensioni della stringa da restituire */
size_t retSize;
/* Dimensione massima di ret se viene allocata preventivamente (e non riallocata ad ogni sostituzione) */
const size_t retMaxSize=8192;
/* Flag che indica l'approccio utilizzato (allocazione immediata o riallocazione ad ogni sostituzione) */
enum AllocMode
{
inAdvance,
onDemand
} allocMode;
/* Verifica se per caso è stata passata qualche stringa nulla */
if(!(searchLength&&replaceLength&&strLength))
return NULL;
/* Calcola le dimensioni della stringa da allocare nel caso peggiore */
retSize=strLength+((replaceLength<searchLength)?0:(strLength/searchLength*(replaceLength-searchLength)))+1;
/* Controlla se le dimensioni così calcolate sforano il nostro limite
se retSize==strLength significa che Replace è più corta di Search, per cui
non dovremo riallocare niente (si fa ricadere nel caso allocMode=onDemand */
if(retSize>retMaxSize && retSize!=strLength)
{
/* In questo caso riallocheremo la memoria ogni volta
Intanto allochiamo in tutto quanta memoria ci serve per effettuare
una copia senza sostituzioni della stringa (il minimo indispensabile) */
retSize=strLength+1;
allocMode=onDemand;
}
else
allocMode=inAdvance;
/* Alloca la memoria */
if((ret=malloc(retSize))==NULL)
return NULL;
/* Non si sbaglia mai a NUL-terminare i buffer, anche se vuoti */
*ret=0;
/* Cicla su ogni carattere */
for(readPtr=Str,writePtr=ret;*readPtr;readPtr++,writePtr++)
{
/* Verifica se al carattere corrente c'è la stringa da cercare */
if(!strncmp(readPtr,Search,searchLength))
{
/* Se l'allocazione è on-demand rialloca ret */
if(allocMode==onDemand)
{
/* Salva l'offset tra ret e writePtr */
ptrdiff_t writeOffset=writePtr-ret;
/* Rialloca la memoria */
if((ret=realloc(ret,retSize+replaceLength))==NULL)
return NULL;
/* Aggiorna retSize */
retSize+=replaceLength;
/* Aggiorna writePtr (qualora fosse cambiato ret) */
writePtr=ret+writeOffset;
}
/* Copia la stringa sostitutiva in fondo alla nuova stringa */
strcpy(writePtr,Replace);
/* Aggiorna i puntatori */
writePtr+=replaceLength-1;
readPtr+=searchLength-1;
}
else
{
/* Copia il carattere */
*writePtr=*readPtr;
}
}
/* Non si sbaglia mai a NUL-terminare i buffer */
*writePtr=0;
/* Se è stata allocata memoria in eccesso, la dealloca */
ret=realloc(ret,strlen(ret)+1);
return ret;
}
int main()
{
char * str;
str=ReplaceString("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean scelerisque, justo id ultrices congue, sapien elit sollicitudin enim, id tempor mi felis vitae magna. Maecenas at congue lorem. Aenean in leo eget ipsum mattis lacinia ut at enim. Suspendisse dolor odio, cursus vel volutpat eget, convallis quis felis. Sed placerat magna arcu, eu posuere leo. Donec dolor est, posuere vitae porta eget, egestas sed sem. Morbi tempor facilisis felis ut iaculis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sit amet nisi nec velit volutpat venenatis. Vestibulum placerat, augue a venenatis blandit, neque justo ultricies eros, in tristique velit orci non libero.","a","zuzzurellone");
if(str==NULL)
{
fputs("Errore",stderr);
}
else
{
puts(str);
free(str);
}
return 0;
}