DOMANDA Eliminare gli spazi da una frase con programma in C

Pubblicità
Perche ? In un moderno pc copiare 20 caratteri o fare una strlen e' uno sforzo inesistente.

Non le ho usate a caso, ma perche' il mio programma risulta piu' facilmente leggibile e comprensibile da chi impara.
Le funzioni di libreria sono gia scomodate con printf.

In oltre, hai scritto un buon codice, ma alcune note sul tuo C
- si usa un coding style conforme in genere, non f=p prima e f = p dopo, ma o sempre f = p o sempre f=p (spazi attorno all'uguale).
- non si dovrebbe scrivere codice nella stessa riga dell'if per guadagnare una riga, si puo ma e' una pratica non tanto pulita

soluzione "stringata" con puntatori

C:
#include <stdio.h>

int main()
{
        char frase[] = "   Frase   di prova  del programma ";
        char *p = frase, *q = frase;

        while (*p++)
                (*p != ' ') ? *q++ = *p : 0;
   
        *q = 0;

        printf("frase: %s\n", frase);

        return 0;
}
 
Ultima modifica:
Personalmente non mi sono soffermato più di tanto sul filone aperto da @bigendian perché l'ho visto principalmente come un "gioco" volto a ridurre le righe di codice; in ogni caso unendo il gioco alle prestazioni si potrebbe scrivere qualcosa del genere:
C:
#include <stdio.h>

int main()
{
    char s[] = "  F  R     A    S  E     ";
    for(char *p1 = s, *p2 = s; *p2; *p1 == ' ' ? *(++p1) : (*p2++ = *p1++));
    printf("%s\n", s);
}

Ci tengo a precisare che non è una critica rivolta @BrutPitt (che ovviamente non è tenuto a leggere tutti i precedenti post, e di cui anzi ho anche apprezzato la battuta sulla string-atezza 😁), ma mi fa sorridere il fatto che le stesse cose da me scritte in precedenti messaggi, se riportate in seguito da qualcun'altro, diventano improvvisamente meritevoli di un like!
Ovviamente non mi riferisco solo a questo caso specifico, ma è un andazzo che va avanti da tempo; evidentemente i like vanno più alla persona che al contenuto... non che me ne freghi qualcosa, ma volevo farlo presente! 😀
 
Personalmente non mi sono soffermato più di tanto sul filone aperto da @bigendian perché l'ho visto principalmente come un "gioco" volto a ridurre le righe di codice; in ogni caso unendo il gioco alle prestazioni si potrebbe scrivere qualcosa del genere:
C:
#include <stdio.h>

int main()
{
    char s[] = "  F  R     A    S  E     ";
    for(char *p1 = s, *p2 = s; *p2; *p1 == ' ' ? *(++p1) : (*p2++ = *p1++));
    printf("%s\n", s);
}

Ci tengo a precisare che non è una critica rivolta @BrutPitt (che ovviamente non è tenuto a leggere tutti i precedenti post, e di cui anzi ho anche apprezzato la battuta sulla string-atezza 😁), ma mi fa sorridere il fatto che le stesse cose da me scritte in precedenti messaggi, se riportate in seguito da qualcun'altro, diventano improvvisamente meritevoli di un like!
Ovviamente non mi riferisco solo a questo caso specifico, ma è un andazzo che va avanti da tempo; evidentemente i like vanno più alla persona che al contenuto... non che me ne freghi qualcosa, ma volevo farlo presente! 😀
Dai, l'ho messo anche a te qui, te lo sei meritato... nonostante la parte che ho evidenziato in grassetto. 🤣

Non entro nello specifico delle performance / ottimizzazioni però, andrebbe verificato.
 
Perche ? In un moderno pc copiare 20 caratteri o fare una strlen e' uno sforzo inesistente.

Non le ho usate a caso, ma perche' il mio programma risulta piu' facilmente leggibile e comprensibile da chi impara.
Le funzioni di libreria sono gia scomodate con printf.

In oltre, hai scritto un buon codice, ma alcune note sul tuo C
- si usa un coding style conforme in genere, non f=p prima e f = p dopo, ma o sempre f = p o sempre f=p (spazi attorno all'uguale).
Nulla da eccepire: in un codice per l'eliminazione degli spazi... ne ho usati 2 di troppo! 😉
- non si dovrebbe scrivere codice nella stessa riga dell'if per guadagnare una riga, si puo ma e' una pratica non tanto pulita
Non era per guadagnare una riga, e' proprio mia consuetudine farlo:
Esempio di codice pubblicato
... anzi mi sono "trattenuto" da accorpare tutto alla medesima riga del for ... 😇

soluzione "stringata" con puntatori

C:
#include <stdio.h>

int main()
{
        char frase[] = "   Frase   di prova  del programma ";
        char *p = frase, *q = frase;

        while (*p++)
                (*p != ' ') ? *q++ = *p : 0;
 
        *q = 0;

        printf("frase: %s\n", frase);

        return 0;
}
Ma perche' non l'hai scritto subito questo codice?
Ammetti che l'altro aveva poco senso... anche come esercizio di stile
E non e' tanto per lo strlen, ma per lo strcpy/memcpy ad ogni spazio... computer moderni o meno, 20 caratteri o intera Divina Commedia

P.S. spero almeno che nessuno studente lo abbia proposto come soluzione 😊

Aggiungo:
Ci tengo a precisare che non è una critica rivolta @BrutPitt (che ovviamente non è tenuto a leggere tutti i precedenti post, e di cui anzi ho anche apprezzato la battuta sulla string-atezza 😁), ma mi fa sorridere il fatto che le stesse cose da me scritte in precedenti messaggi, se riportate in seguito da qualcun'altro, diventano improvvisamente meritevoli di un like!
Ovviamente non mi riferisco solo a questo caso specifico, ma è un andazzo che va avanti da tempo; evidentemente i like vanno più alla persona che al contenuto... non che me ne freghi qualcosa, ma volevo farlo presente! 😀
Ma hai ragione e chiedo venia.
 
Ultima modifica:
Dai, l'ho messo anche a te qui, te lo sei meritato... nonostante la parte che ho evidenziato in grassetto. 🤣
Grazie, ora va molto meglio! 😁
Meglio riderci su e non approfondire la questione!

Per la parte in grassetto, giusto, come con "un", l'apostrofo va solo prima delle parole femminili! 😅
 
@BrutPitt

se lo scopo era che funzioni, il mio codice con memcpy e' chiaro, ti preoccupi dello strlen ma non siamo su un microcontrollore 8 bit :) .
il secondo e' meno leggibile per un principiante,

@M1n021

bello, geniale, unica nota che la definizione dei puntatori dentro al for che nasceva nel c++ non e' portabile. Che ne so, su un compilatore keil 8051 probabilmente da errore. Nel kernel linux ad esempio e' tuttora vietato.

ci vorrebbe piu gente che chiede i compiti :)
 
unica nota che la definizione dei puntatori dentro al for che nasceva nel c++ non e' portabile.
In effetti mi sembra di ricordare che prima del c99 la prima parte del for potesse contenere solo espressioni, ma non dichiarazioni.
Sui forum si vede spesso codice con dichiarazioni fatte all'esterno del for, chissà se questa abitudine è una scelta consapevole per una maggiore portabilità oppure dipende dai vecchi libri su cui studiano i ragazzi o da professori rimasti un po' arretrati?! 😅
 
@BrutPitt

se lo scopo era che funzioni, il mio codice con memcpy e' chiaro, ti preoccupi dello strlen ma non siamo su un microcontrollore 8 bit :) .
il secondo e' meno leggibile per un principiante,
Ma io non mi preoccupavo dello strlen (l'avevo aggiunto ironicamente come "ciliegina sulla torta")

Quello su cui puntavo il dito (ripeto) era/e' l'utilizzo di strcpy/memcpy.
Nel tuo esempio, la frase in questione e' lunga 36 caratteri.
C:
        char frase[] = "   Frase   di prova  del programma ";
La prima volta copi 35 caratteri, poi: 34, 33, 27, 26, 25, 22, 16, 15, 11, 1

Ossia su una frase di 36 caratteri, per toglierne alcuni, ne sposti/copi 245. (senza contare che lo strlen se ne scorre altrettanti)
E la cosa aumenta drasticamente all'aumentare della frase:
Solo a "raddoppiarla", ossia 72 caratteri
C:
        char frase[] = "   Frase   di prova  del programma   Frase   di prova  del programma ";
arriviamo a 886 spostamenti/copie (e strlen se ne scorre altrettanti)

Funzionera' pure, sara pure piu' leggibile per un principiante (opinione opinabile), il codice avra' pure tutti gli spazi al posto giusto e gli if indentati by K&R, avremo (per fortuna) anche computer potentissimi ... ma...

La chiudo qui.
 
Ultima modifica:
In effetti mi sembra di ricordare che prima del c99 la prima parte del for potesse contenere solo espressioni, ma non dichiarazioni.
Sui forum si vede spesso codice con dichiarazioni fatte all'esterno del for, chissà se questa abitudine è una scelta consapevole per una maggiore portabilità oppure dipende dai vecchi libri su cui studiano i ragazzi o da professori rimasti un po' arretrati?! 😅

Possibile si rifacciano all'ANSI C, anche.
Devo dire che guardando il codice del kernel ciò che si fa è dichiarare tutto in cima, solitamente.
Posto che si usano anche in sacco di macro, specie in alcuni subsystem.

Per lavoro sono finito su questa funzione, guarda il "foreach", e nota le varie dichiarazioni: https://github.com/torvalds/linux/b...s/net/ethernet/intel/ixgbe/ixgbe_main.c#L3182

In generale comunque: https://www.kernel.org/doc/html/v6.12/process/coding-style.html

Poi dubito i prof abbiano vere e proprie ragioni quando spiegano a scuola, magari è abitudine... magari sono ricordi del passato. 😁
 
Pubblicità
Pubblicità
Indietro
Top