Frazionare una frase

di il
7 risposte

Frazionare una frase

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;
}

7 Risposte

  • Re: Frazionare una frase

    C'è una cosa orribile: l'uso di lMax.
    Nelle due funzioni è un parametro.
    Nel main è dichiarato come una variabile ma in realtà, di solito, si definisce come costante.
    È opportuno che usi diversi abbiano nomi diversi, evita di confondere le cose.
    malloc( l+1 );
    Perché +1? (VOGLIO UN'EMOTICON CON UN BUG!)
    i<l&&sTmp[i];
    if( i-j==lMax ) {
    
    Spazia con maggior cura.

    strlchr mi pare un pessimo nome: troppo simile a quelli di libreria, rischi confusione. Dare i nomi talvolta è difficile ma è sempre importantissimo.

    Ora ho sonno... ciao!
  • Re: Frazionare una frase

    Nicolap: "C'è una cosa orribile: l'uso di lMax. [ecc.]"

    Questa non l'ho capita.

    nicolap: "Perché +1?"

    Per far spazio al terminatore.

    nicolap: "Spazia con maggior cura."

    La spaziatura non influisce sul funzionamento del programma. Comunque ho capito cosa intendi: avresti preferito i<l && sTmp... e cose del genere. A seconda di come mi "paga l'occhio" scelgo soluzioni di spaziatura diverse.

    nicolap: "strlchr mi pare un pessimo nome: troppo simile a quelli di libreria, rischi confusione."

    Questo l'ho fatto apposta! Volevo "fare il verso" a strrchr(): quella cerca il carattere da destra (dalla fine della stringa - string right character, credo), la mia lo cerca verso sinistra (a partire dal puntatore dato - string left character). E' una bischerata, lo so, ma mi divertiva l'idea.

    Comunque sia, ti ringrazio per aver preso in considerazione le mie righe, anche se non mi hai indicato errori o malfunzionamenti, bensì più che altro questioni "di stile".
  • Re: Frazionare una frase

    AldoBaldo ha scritto:


    nicolap: "C'è una cosa orribile: l'uso di lMax. [ecc.]"

    Questa non l'ho capita.
    Dare lo stesso nome a cose diverse ingenera confusione.

    nicolap: "Spazia con maggior cura."

    La spaziatura non influisce sul funzionamento del programma. Comunque ho capito cosa intendi: avresti preferito i<l && sTmp... e cose del genere. A seconda di come mi "paga l'occhio" scelgo soluzioni di spaziatura diverse.
    Nonsense: si spazia SEMPRE secondo le regole. Le regole te le devi dare tu, in questo caso, ma devono avere un senso.

    Comunque sia, ti ringrazio per aver preso in considerazione le mie righe, anche se non mi hai indicato errori o malfunzionamenti, bensì più che altro questioni "di stile".
    Lo stile è importante perché se hai un "brutto" stile scrivi comunque pessimo codice. La CPU ha una logica inflessibile, se vuoi comunicare le Lei devi adeguarti!
    
            for( size_t j=0, i=0; i<l&&sTmp[i]; ++i ) {
    
    Siamo sempre alle scelte stilistiche: non dichiarare dentro la for una variabile in più che non fa parte del for stesso.

    Ora che il codice lo conosci a memoria ti sembra tutto bello e giusto ma quando ci tornerai sopra in futuro non ne sarai così contento.

    Il codice, a leggerlo, mi sembra giusto.
  • Re: Frazionare una frase

    @AldoBaldo, saper programmare PER PRIMA COSA vuol dire scrivere il codice in modo ORDINATO.

    PRATICAMENTE per TUTTI i linguaggi di programmazione ci sono i MANUALI di STILE che spiegano come si scrive il codice.

    ll codice VA SCRITTO USANDO QUELLO STILE. NON SI mescolano stili, NON CI SI INVENTA UNO STILE PERSONALE, MA SI USA LO STILE indicato.

    Se e' vero che al compilatore non frega nulla dello stile, E' ALTRETTANTO VERO CHE NON E" IL COMPILATORE a scrivere e a correggere il codice.

    Quindi, SCRIVERE BENE il codice e' anche PIU' IMPORTANTE che scrivere codice che funziona.

    Perche', e lo imparerai a tue spese, trovare l'errore in un codice che FUNZIONA PER SBAGLIO e' un bagno di sangue!

    E mettere le mani su del codice scritto con i piedi ti fa' pentire di aver scelto questo mestiere
  • Re: Frazionare una frase

    Infatti per me è un passatempo, non un mestiere.

    Comunque sia, quel codice è stato riformattato con il plug-in per la riformattazione automatica di Code::Blocks, per cui rispetta lo stile tipico delle impostazioni di default di quel plug-in (che ho usato proprio per evitare polemiche formali e mantenere l'attenzione sulla sostanza). Non credo che qualche spazio malmesso o un nome di variabile "atipico" possano impedirvi di esprimere il parere che vi ho cortesemente chiesto, siete troppo esperti per non capire cosa ho scritto e se le due funzionicine da quattro soldi hanno o non hanno difetti sostanziali. Dunque, non volete rispondermi. Pazienza, come ho detto per me è un passatempo, e sicuramente voi non siete obbligati ad alcunché. Dunque la chiudo qui, fate finta che non abbia chiesto niente e amici come prima.

  • Re: Frazionare una frase

    AldoBaldo ha scritto:


    Infatti per me è un passatempo, non un mestiere.

    Non credo che qualche spazio malmesso o un nome di variabile "atipico" possano impedirvi di esprimere il parere che vi ho cortesemente chiesto, siete troppo esperti per non capire cosa ho scritto e se le due funzionicine da quattro soldi hanno o non hanno difetti sostanziali. Dunque, non volete rispondermi.
    Ciao AldoBaldo. In realtà quello che chiedi tu non è affatto a tempo zero. Anche se le chiami funzioncine, il dominio a cui si applicano è molto vasto, quindi diventa faticoso valutarne la robustezza.

    Il mio consiglio è: perché non fai unit testing? Come hai detto tu, il problema è risolto e strarisolto. Perché non paragoni i risultati delle tue funzioni con altre funzioni di test che comprendono i già noti strttok, strrchr etc., applicandoli alle stesse stringhe per vedere se i risultati sono coerenti? Magari come input gli passi un file di testo bello corposo
  • Re: Frazionare una frase

    Weierstrass, non avevo la più pallida idea di cosa fosse 'sto "unit testing", per cui ho cercato brevemente. Direi che è una proposta sensata, raccolgo ancora qualche informazione e provo a farlo. Grazie per lo spunto (basta poco per far contento un hobbista).

    P.S. In effetti è una cosa che ho già fatto più e più volte senza sapere che si chiamasse "unit testing" e che ci fossero delle tecniche "standard" per procedere in modo, diciamo così, "organico". Anche solo sapere che ci sono articoli dedicati in merito è un bell'aiuto.
Devi accedere o registrarti per scrivere nel forum
7 risposte