Per un giochino da quattro soldi che sto mettendo insieme per passatempo, avrei bisogno di frammentare una stringa su più righe che abbiano ciascuna una quantita' di caratteri che non superi un certo massimo. So che è una questione che è già stata risolta e strarisolta e che se cerco sul web trovo sicuramente qualcosa di già pronto, però... che passatempo sarebbe? Dunque ho provato a elaborare una mia soluzione e vi chiedo se ha qualche pecca (non parlo di inefficienze, parlo di errori o difetti grossolani ai quali posso non aver pensato, magari in presenza di "casi limite"). Ecco il codice del programma di prova, in C (non C++):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*==============================================================================
Cerca un carattere c nella stringa s, arretrando fino a un massimo di lMax
caratteri. Restituisce il puntatore al carattere trovato, oppure NULL se il
carattere non e' stato trovato.
==============================================================================*/
char *strlchr( char *s, size_t lMax, char c )
{
if( s )
for( size_t i=0; i<lMax; ++i )
if( *(s-i)==c )
return s-i;
return NULL;
}
/*==============================================================================
Modifica la stringa s, sostituendone alcuni caratteri ' ' con '\n' per dividerla
in porzioni di lunghezza massima lMax. Se la suddivisione avviene senza intoppi
restituisce 1, altrimenti restituisce 0 e lascia intatta la stringa originale.
==============================================================================*/
int fraziona_frase( char *s, size_t lMax )
{
if( s && lMax>0 ) {
size_t l = strlen(s);
char *sTmp = malloc( l+1 );
if( !sTmp ) return 0;
memcpy( sTmp, s, l+1 );
for( size_t j=0, i=0; i<l&&sTmp[i]; ++i ) {
if( i-j==lMax ) {
char *p = strlchr(sTmp+i,lMax,' ');
if( p ) {
*p = '\n';
}
else {
free(sTmp);
return 0;
}
j = p-sTmp;
}
else if( '\n'==sTmp[i] ) {
j=i;
}
}
memcpy( s, sTmp, l+1 );
free( sTmp );
return 1;
}
return 0;
}
int main()
{
char frase_di_prova[] = "Una frase di prova, da dividere in sezioni con degli \"a capo\" strategici.";
size_t lMax = 12;
if( !fraziona_frase(frase_di_prova,lMax) )
puts( "Frase non frazionabile." );
else
printf( "%s\n\n", frase_di_prova );
return 0;
}