#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "utilita_stringhe_dinamiche.h"
/*==============================================================================
Riceve il puntatore ad una stringa C, ne effettua una copia in un'area di
memoria dinamica appositamente allocata, restituisce il puntatore alla memoria
allocata (NULL se l'allocazione fallisce).
Spetta al chiamante liberare con libera_buffer() la memoria allocata.
==============================================================================*/
char *duplica_stringa( const char *str ) {
char *tmp = NULL;
if( str ) { // verifica che il parametro s sia una stringa valida
size_t l = strlen(str)+1; // +1 per includere il terminatore
if( (tmp=malloc(l)) ) memcpy( tmp, str, l );
}
return tmp;
}
/*==============================================================================
Alloca la quantita' di memoria indicata da dim (dim NON include il carattere
terminatore) e copia la stringa str nello spazio di memoria allocato. Se dim e'
minore della lunghezza corrente della stringa, la stringa viene troncata. Se dim
e' maggiore della lunghezza corrente della stringa, lo spazio eccedente viene
impostato su una serie di zeri. Restituisce il puntatore alla memoria allocata
(NULL se l'allocazione fallisce).
Spetta al chiamante liberare con libera_buffer() la memoria allocata.
==============================================================================*/
char *dimensiona_stringa( const char *str, size_t dim ) {
char *tmp = NULL;
if( str ) { // verifica che il parametro s sia una stringa valida
tmp = calloc( dim+1, sizeof(*tmp) );
if( tmp ) { // allocazione riuscita, copiamo
size_t l = strlen( str );
strncpy( tmp, str, l<dim?l:dim );
}
}
return tmp;
}
/*==============================================================================
Inserisce la stringa agg nella posizione pos della stringa s. Se pos eccede la
lunghezza della stringa, l'aggiunta viene effettuata in coda alla stringa
stessa. Colloca la stringa risultante in un'area di memoria dinamica
appositamente allocata e restituisce il puntatore alla memoria allocata (NULL se
l'allocazione fallisce).
Spetta al chiamante liberare con libera_buffer() la memoria allocata.
==============================================================================*/
char *inserisci_stringa( const char *str, const char *agg, size_t pos ) {
char *tmp = NULL;
if( str && agg ) {
size_t lStr = strlen( str );
size_t lAgg = strlen( agg );
tmp = malloc( lStr+lAgg+1 );
if( tmp ) { // allocazione riuscita, inseriamo
if( pos > lStr ) pos = lStr;
memcpy( tmp, str, pos );
memcpy( tmp+pos, agg, lAgg );
memcpy( tmp+pos+lAgg, str+pos, lStr-pos+1 );
}
} else if( str ) tmp = duplica_stringa( str );
return tmp;
}
/*==============================================================================
Converte in stringa il valore indicato da n, quindi lo inserisce nella posizione
pos della stringa s. Se pos eccede la lunghezza della stringa, l'aggiunta viene
effettuata in coda alla stringa stessa. Colloca la stringa risultante in un'area
di memoria dinamica appositamente allocata e restituisce il puntatore alla
memoria allocata (NULL se l'allocazione fallisce).
Spetta al chiamante liberare con libera_buffer() la memoria allocata.
==============================================================================*/
char *inserisci_intero( const char *str, int n, size_t pos ) {
char buff[32];
sprintf( buff, "%d", n );
return inserisci_stringa( str, buff, pos );
}
/*==============================================================================
Sostituisce nella stringa str tutte le occorrenze dei caratteri indicati nella
stringa orig con i caratteri indicati nelle stesse posizioni nella stringa sost.
Ad esempio, sostituisci_caratteri( "Provetta", "Pt", "Bd" ) da' come esito la
stringa "Brovedda". Colloca la stringa risultante in un'area di memoria dinamica
appositamente allocata e restituisce il puntatore alla memoria allocata (NULL se
l'allocazione fallisce). Spetta al chiamante liberare con libera_buffer() la
memoria allocata.
==============================================================================*/
char *sostituisci_caratteri(
const char *str, const char *orig, const char *sost ) {
char *tmp = NULL;
if( str && orig && sost ) {
size_t lStr = strlen( str );
size_t lOrig = strlen( orig );
size_t lSost = strlen( sost );
if( lStr && lOrig && lSost && lOrig==lSost ) {
size_t i, j;
tmp = duplica_stringa( str );
if( tmp ) { // allocazione riuscita, sostituiamo
for( i=0; i<lStr; ++i )
for( j=0; j<lOrig; ++j )
if( tmp[i] == orig[j] )
tmp[i] = sost[j];
}
}
} else if( str ) tmp = duplica_stringa( str );
return tmp;
}
/*==============================================================================
Sostituisce un frammento di l caratteri della stringa s con la stringa sost, a
partire dalla posizione pos (sost puo' anche essere piu' lungo o piu' corto di l
caratteri). Colloca la stringa risultante in un'area di memoria dinamica
appositamente allocata e restituisce il puntatore alla memoria allocata (NULL se
l'allocazione fallisce).
Spetta al chiamante liberare con libera_buffer() la memoria allocata.
==============================================================================*/
char *sostituisci_frammento(
const char *str, const char *sost, size_t pos, size_t l ) {
char *tmp = NULL;
if( str && sost ) {
size_t lStr = strlen( str );
size_t lSost = strlen( sost );
if( pos > lStr ) pos = lStr;
if( pos+l > lStr ) l = lStr-pos;
tmp = malloc( (lStr-l)+lSost+1 );
if( tmp ) { // allocazione riuscita, sostituiamo
memcpy( tmp, str, pos );
memcpy( tmp+pos, sost, lSost );
memcpy( tmp+pos+lSost, str+pos+l, lStr-pos-l+1 );
}
} else if( str ) tmp = duplica_stringa( str );
return tmp;
}
/*==============================================================================
Cerca nella stringa str le ricorrenze della stringa ptrn e le sostituisce con la
stringa sost. Colloca la stringa risultante in un'area di memoria dinamica
appositamente allocata e restituisce il puntatore alla memoria allocata (NULL se
l'allocazione fallisce).
Spetta al chiamante liberare con libera_buffer() la memoria allocata.
==============================================================================*/
char *sostituisci_frammenti(
const char *str, const char *ptrn, const char *sost ) {
char *tmp = NULL; // per il buffer dell'esito
if( str && ptrn && sost ) { // verifica la validita' dei parametri
// quanto e' lungo il pattern da sostituire?
size_t lPtrn = strlen( ptrn );
if( lPtrn != 0 ) { // il pattern da sostituire non puo' essere vuoto
// quante volte ptrn ricorre nella stringa?
size_t qRic; // qRic = quantita' di ricorrenze (del pattern in str)
const char *pPtrn = strstr( str, ptrn );
for( qRic=0; pPtrn; ++qRic )
pPtrn = strstr( ++pPtrn, ptrn );
if( qRic>0 ) { // il pattern deve essere presente almeno una volta
// rileva la lunghezza delle parti "in gioco"
size_t lStr = strlen( str ); // la lunghezza di str
size_t lSost = strlen( sost ); // lunghezza delle sostituzioni
// alloca il buffer per la stringa risultante dalle sostituzioni
tmp = malloc( lStr - lPtrn*qRic + lSost*qRic + 1 );
if( tmp ) { // allocazione riuscita, sostituiamo
const char *pOrig; // il punto di str dal quale copiare
char *pDest; // punta al punto di tmp nel quale copiare
size_t i;
for( pOrig=str, pDest=tmp, i=0; i<=qRic; ++i ) {
if( (pPtrn=strstr(pOrig,ptrn)) ) {
memcpy( pDest, pOrig, pPtrn-pOrig );
pDest += pPtrn-pOrig;
pOrig += pPtrn-pOrig + lPtrn;
memcpy( pDest, sost, lSost );
pDest += lSost;
} else memcpy( pDest, pOrig, lStr-(pOrig-str)+1 );
}
}
} else tmp = duplica_stringa( str );
} else tmp = duplica_stringa( str );
} else if( str ) tmp = duplica_stringa( str );
return tmp;
}
/*==============================================================================
Cerca nella stringa str le ricorrenze della stringa ptrn e le sostituisce,
nell'ordine, con le stringhe contenute nell'array di stringhe puntato da sost.
L'array deve contenere la quantita' di stringhe specificata dal parametro qSost.
Se ci sono discrepanze tra la quantita' delle ricorrenze di ptrn in str e il
valore di qSost, prevale la quantita' minore.
Colloca la stringa risultante in un'area di memoria dinamica appositamente
allocata e restituisce il puntatore alla memoria allocata (NULL se l'allocazione
fallisce).
Spetta al chiamante liberare con libera_buffer() la memoria allocata.
==============================================================================*/
char *sostituisci_segnaposto(
const char *str, const char *ptrn, const char **sost, size_t qSost ) {
size_t *lSost = NULL;
char *tmp = NULL;
size_t i;
// verifica la validita' dei parametri
if( sost ) {
for( i=0; i<qSost; ++i )
if( !sost[i] )
return duplica_stringa( str );
} else return duplica_stringa( str );
if( str && ptrn ) { // verifica la validita' dei parametri
// quant'e' lungo il pattern da sostituire?
size_t lPtrn = strlen( ptrn );
if( lPtrn != 0 ) { // il pattern da sostituire non puo' essere vuoto
// quante volte ptrn ricorre nella stringa?
size_t qRic; // qRic = quantita' di ricorrenze (del pattern in str)
const char *pPtrn = strstr( str, ptrn ); // la posizione del pattern
for( qRic=0; pPtrn; ++qRic )
pPtrn = strstr( ++pPtrn, ptrn );
if( qRic > qSost ) qRic = qSost; else qSost = qRic;
// alloca un buffer per la lunghezza delle stringhe sostitutive
if( (lSost=calloc(qSost,sizeof(*lSost))) == NULL ) return tmp;
if( qRic>0 ) { // il pattern deve essere presente almeno una volta
size_t lStr = strlen( str ); // la lunghezza di str
size_t totLSost = 0; // la lunghezza totale delle sostituzioni
// rileva la lunghezza d'ognuna delle parti sostitutive
for( i=0; i<qSost; ++i ) {
lSost[i] = strlen( sost[i] );
totLSost += lSost[i]; // aggiunge alla somma totale
}
// alloca il buffer per la stringa risultante dalle sostituzioni
tmp = malloc( lStr - lPtrn*qRic + totLSost + 1 );
if( tmp ) { // allocazione riuscita, sostituiamo
const char *pOrig; // il punto di str dal quale copiare
char *pDest; // punta al punto di tmp nel quale copiare
for( pOrig=str, pDest=tmp, i=0; i<=qRic; ++i ) {
if( (pPtrn=strstr(pOrig,ptrn)) ) {
memcpy( pDest, pOrig, pPtrn-pOrig );
pDest += pPtrn-pOrig;
pOrig += pPtrn-pOrig + lPtrn;
memcpy( pDest, sost[i], lSost[i] );
pDest += lSost[i];
} else memcpy( pDest, pOrig, lStr-(pOrig-str)+1 );
}
}
} else tmp = duplica_stringa( str );
} else tmp = duplica_stringa( str );
} else if( str ) tmp = duplica_stringa( str );
free( lSost );
return tmp;
}
/*==============================================================================
Riceve il puntatore ad un puntatore ad una stringa C collocata in un'area di
memoria allocata dinamicamente, libera con free() quella memoria e annulla il
puntatore.
==============================================================================*/
void libera_buffer( char **buffer ) {
if( buffer ) if( *buffer ) { free( *buffer ); *buffer = NULL; }
}