Esercizio stringhe C

di il
15 risposte

Esercizio stringhe C

Salve a tutti,dovrei sviluppare una function in c che dati come parametri di input una stringa che rappresenta un testo in italiano,determina e restituisce come parametri di output la parola di lunghezza massima contenuta nel testo e appunto la sua lunghezza.
IL codice che ho sviluppato è questo,il problema è che la printf nel main non mi visualizza la parola ma solo la sua lunghezza..Qualcuno puo aiutarmi e magari darmi anche qualche consiglio se ho sbagliato o posso migliorare qualcosa?
#include<stdio.h>
#include<string.h>
void LongerWord(char [],int *,char *);
int main(){
int lunghezza;
char testo[100],parola[20];
printf("Inserire testo: ");
gets(testo);
printf("Hai inserito: ");
puts(testo);
LongerWord(testo,&lunghezza,parola);
printf("La parola piu lunga e' %s,lunga %d caratteri",parola,lunghezza);
return 0;

}
void LongerWord(char testo[],int *max,char *longer)
{
int i,cnt=0,n;
n=strlen(testo);
for(i=0;i<n;i++){
    if(testo[i]==" " || testo[i]=='\n')
 {
    if(*max<cnt) {
        *max=cnt;
        strncpy(longer,&testo[i-cnt],cnt+1);
                 }
        cnt=0;
 }
 else cnt++;
}
}

15 Risposte

  • Re: Esercizio stringhe C

    Tentando la compilazione con GCC del tuo codice, ottengo questi avvisi:

    In function ‘main’:
    :8:1: warning: ‘gets’ is deprecated (declared at /usr/include/stdio.h:638) [-Wdeprecated-declarations]
    gets(testo);
    ^
    In function ‘LongerWord’:
    :21:16: warning: comparison between pointer and integer [enabled by default]
    if(testo==" " || testo=='\n')
    ^
    nella funzione "main":
    : attenzione: the `gets' function is dangerous and should not be used.
  • Re: Esercizio stringhe C

    In realtà il tuo programma ha un errore, probabilmente segnalato solo come warning dal tuo compilatore:
    
    if(testo[i]==" " || testo[i]=='\n')
    
    Deve essere
    
    if(testo[i]==' ' || testo[i]=='\n')
    
    Stai confrontando un carattere, quindi il carattere, come hai fatto per il carattere newline, deve essere messo fra apici semplici.

    Inoltre la funzione gets è deprecata dal c99 e completamente eliminata dal c11. Sostituiscila con fgets
    
    fgets(testo, sizeof(testo), stdin);
    
  • Re: Esercizio stringhe C

    LP ... hai messo due spazi ... deve essere uno solo ...
  • Re: Esercizio stringhe C

    Ho una serie di perplessità.
    1) Perchè la funzione è void, invece di ritornare direttamente la lunghezza?
    2) cosa succede se passi un testo NULL?
    3) cosa succede se passi un "longer" null?
    4) come fai a sapere che dentro "longer" ci sta il testo (strncpy) ? se longer punta poniamo a un vettore di 4 caratteri, e la la stringa è lunga 5, che accade?
    5) perchè la chiami "LongerWord" (intendo con una notazione simil-polacca del tutto inutile)?
    6) che succede se non c'è uno zero (che termini testo), cioè strlen(testo)?
    7) - più sottile, e nel tuo caso inutile - cambia qualcosa nell'OR? O meglio se il compilatore ti cambiasse l'ordine di valutazione?
  • Re: Esercizio stringhe C

    oregon ha scritto:


    LP ... hai messo due spazi ... deve essere uno solo ...
    Ooops. Corretto
  • Re: Esercizio stringhe C

    +m2+ ha scritto:


    Ho una serie di perplessità.
    1) Perchè la funzione è void, invece di ritornare direttamente la lunghezza?
    2) cosa succede se passi un testo NULL?
    3) cosa succede se passi un "longer" null?
    4) come fai a sapere che dentro "longer" ci sta il testo (strncpy) ? se longer punta poniamo a un vettore di 4 caratteri, e la la stringa è lunga 5, che accade?
    5) perchè la chiami "LongerWord" (intendo con una notazione simil-polacca del tutto inutile)?
    6) che succede se non c'è uno zero (che termini testo), cioè strlen(testo)?
    7) - più sottile, e nel tuo caso inutile - cambia qualcosa nell'OR? O meglio se il compilatore ti cambiasse l'ordine di valutazione?

    Innanzitutto grazie a tutti per l'aiuto e scusate il ritardo per la risposta.Dalle tue perplessita capisco che ne sai molto ma molto di piu di me,io purtroppo sono alle prime armi.Scrivendo il codice,ho dato per scontato(è sbagliato,lo so) che non venga fornito un testo NULL,ho dichiarato longer in modo tale da contenere la parola piu lunga,per ritornare la lunghezza come vedi ho usato un puntatore e il nome della funzione credo sia una cosa di poco conto.Il codice è sicuramente da migliorare in modo tale che funzioni per tutti i casi pero l'ho scritto cosi per capire i passaggi dei parametri tra le funzioni.Se dovessi trovare l'errore che non mi permette di restituire la stringa,quale sarebbe?
  • Re: Esercizio stringhe C

    Gnocchino ha scritto:


    Se dovessi trovare l'errore che non mi permette di restituire la stringa,quale sarebbe?

    ??????

    Non hai ancora risolto?
  • Re: Esercizio stringhe C

    Purtroppo no anche perche ho ripreso stamattina dopo il week..Ho corretto l'if che mi avete fatto notare ma ancora devo capire il perche non riesco a visualizzare la parola
  • Re: Esercizio stringhe C

    Gnocchino ha scritto:


    Purtroppo no anche perche ho ripreso stamattina dopo il week..Ho corretto l'if che mi avete fatto notare ma ancora devo capire il perche non riesco a visualizzare la parola
    Effettivamente, riguardando la mia risposta, manca ancora una cosa.

    La funzione strncpy copia la stringa, ma se vedi IL MANUALE (che si deve sempre guardare per capre come lavorano le funzioni che si utilizzano) c'è una bella indicazione:

    [qoute]
    Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
    [/quote]

    Questo significa che la tua variabile parola, nel caso in cui la parola non sia l'ultima del testo inserito, non ha il terminatore. Quindi devi aggiungerlo tu a mano. Puoi procedere in due modi:
    1) Modo corretto, aggiungi dopo la strncpy il nul-terminator
    
    strncpy(longer, &testo[i - cnt], cnt);
    longer[cnt] = '\0';
    
    2) modo funzionante, ma solamente se si analizza un testo per ogni esecuzione del programma: basta dichiarare:
    
    char parola[20] = {0};
    
    Perchè in questa maniera, quando viene allocato l'array tutti i suoi valori sono inizializzati a 0. Stessa cosa se sposti la dichiarazione dell'array e lo dichiari globale, in quanto le variabili locali fanno parte di una section che è zero-ata all'avvio dell'applicazione.

    QUI puoi vedere il programma corretto e funzionante.
  • Re: Esercizio stringhe C

    Gnocchino ha scritto:


    ...Dalle tue perplessita capisco che ne sai molto ma molto di piu di me,io purtroppo sono alle prime armi...
    Bhè programmo in C dal 1991, e in C++ dal 1993 (ho perfino un autografo di Stroustrup)

    Guardando l'ultimo programma faccio notare che...
    1) cosa succede se testo punta a un'area di memoria NON null-terminata? (strlen)
    2) gli interi possono essere signed (col segno)? cosa succede se max è negativo?
    3) se longer punta a vuoto?
    4) perchè la funzione è void, invece di tornare la lunghezza (collegato al punto precedente)
    5) in generale l'inizializzazione a zero l'eviterei, è una pessima consuetudine, foriera di disastri immani
    6) "trucchetto": talvolta conviene usare brutamente sprintf per avere la null-terminazione automatica (vabbè ma questo non ti riguarda a questo livello)
    7) cambia qualcosa se il terminatore della stringa è 10-13 anzichè 10 (o 13) ? In pratica il programma è perfettamente portabile tra Windows e Linux (per banalizzare)
    - questa però è molto oltre - siamo sicuri che char vada bene, o quanto sia un char (mi riferisco a utf8, quindi portabilità con lingue non latine, tipo russo per dirne una)
    9) come distingui un parametro in ingresso, da uno in uscita? consiglio di usare una banale consuetudine: chiamare i_qualcosa quelli in ingresso, e o_qualcosa quelli in uscita. Esempio: max è un parametro in INGRESSO dalla funzione, o uno in uscita? Io non so dirlo (guardando la definizione della funzione). Potrebbe (anzi dovrebbe) essere secondo logica professionale la lunghezza massima di testo[]

    Insomma come puoi vedere anche fare una funzioncella banale come quella in oggetto, a livello professionale e non accademico-didattico, non è banale come può sembrare all'apparenza.
  • Re: Esercizio stringhe C

    LPs ha scritto:


    Gnocchino ha scritto:


    Purtroppo no anche perche ho ripreso stamattina dopo il week..Ho corretto l'if che mi avete fatto notare ma ancora devo capire il perche non riesco a visualizzare la parola
    Effettivamente, riguardando la mia risposta, manca ancora una cosa.

    La funzione strncpy copia la stringa, ma se vedi IL MANUALE (che si deve sempre guardare per capre come lavorano le funzioni che si utilizzano) c'è una bella indicazione:

    [qoute]
    Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
    Questo significa che la tua variabile parola, nel caso in cui la parola non sia l'ultima del testo inserito, non ha il terminatore. Quindi devi aggiungerlo tu a mano. Puoi procedere in due modi:
    1) Modo corretto, aggiungi dopo la strncpy il nul-terminator
    
    strncpy(longer, &testo[i - cnt], cnt);
    longer[cnt] = '\0';
    
    2) modo funzionante, ma solamente se si analizza un testo per ogni esecuzione del programma: basta dichiarare:
    
    char parola[20] = {0};
    
    Perchè in questa maniera, quando viene allocato l'array tutti i suoi valori sono inizializzati a 0. Stessa cosa se sposti la dichiarazione dell'array e lo dichiari globale, in quanto le variabili locali fanno parte di una section che è zero-ata all'avvio dell'applicazione.

    QUI puoi vedere il programma corretto e funzionante.[/quote]

    Guardando lo stdout ottieni il mio stesso risultato,la printf non visualizza la parola piu lunga :/
  • Re: Esercizio stringhe C

    +m2+ ha scritto:


    Gnocchino ha scritto:


    ...Dalle tue perplessita capisco che ne sai molto ma molto di piu di me,io purtroppo sono alle prime armi...
    Bhè programmo in C dal 1991, e in C++ dal 1993 (ho perfino un autografo di Stroustrup)

    Guardando l'ultimo programma faccio notare che...
    1) cosa succede se testo punta a un'area di memoria NON null-terminata? (strlen)
    2) gli interi possono essere signed (col segno)? cosa succede se max è negativo?
    3) se longer punta a vuoto?
    4) perchè la funzione è void, invece di tornare la lunghezza (collegato al punto precedente)
    5) in generale l'inizializzazione a zero l'eviterei, è una pessima consuetudine, foriera di disastri immani
    6) "trucchetto": talvolta conviene usare brutamente sprintf per avere la null-terminazione automatica (vabbè ma questo non ti riguarda a questo livello)
    7) cambia qualcosa se il terminatore della stringa è 10-13 anzichè 10 (o 13) ? In pratica il programma è perfettamente portabile tra Windows e Linux (per banalizzare)
    - questa però è molto oltre - siamo sicuri che char vada bene, o quanto sia un char (mi riferisco a utf8, quindi portabilità con lingue non latine, tipo russo per dirne una)
    9) come distingui un parametro in ingresso, da uno in uscita? consiglio di usare una banale consuetudine: chiamare i_qualcosa quelli in ingresso, e o_qualcosa quelli in uscita. Esempio: max è un parametro in INGRESSO dalla funzione, o uno in uscita? Io non so dirlo (guardando la definizione della funzione). Potrebbe (anzi dovrebbe) essere secondo logica professionale la lunghezza massima di testo[]

    Insomma come puoi vedere anche fare una funzioncella banale come quella in oggetto, a livello professionale e non accademico-didattico, non è banale come può sembrare all'apparenza.


    Potresti consigliarmi del materiale da cui studiare?Non so qualche libro oppure qualcosa su internet
  • Re: Esercizio stringhe C

    Gnocchino ha scritto:


    LPs ha scritto:


    Gnocchino ha scritto:


    Purtroppo no anche perche ho ripreso stamattina dopo il week..Ho corretto l'if che mi avete fatto notare ma ancora devo capire il perche non riesco a visualizzare la parola
    Effettivamente, riguardando la mia risposta, manca ancora una cosa.

    La funzione strncpy copia la stringa, ma se vedi IL MANUALE (che si deve sempre guardare per capre come lavorano le funzioni che si utilizzano) c'è una bella indicazione:

    [qoute]
    Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
    Questo significa che la tua variabile parola, nel caso in cui la parola non sia l'ultima del testo inserito, non ha il terminatore. Quindi devi aggiungerlo tu a mano. Puoi procedere in due modi:
    1) Modo corretto, aggiungi dopo la strncpy il nul-terminator
    
    strncpy(longer, &testo[i - cnt], cnt);
    longer[cnt] = '\0';
    
    2) modo funzionante, ma solamente se si analizza un testo per ogni esecuzione del programma: basta dichiarare:
    
    char parola[20] = {0};
    
    Perchè in questa maniera, quando viene allocato l'array tutti i suoi valori sono inizializzati a 0. Stessa cosa se sposti la dichiarazione dell'array e lo dichiari globale, in quanto le variabili locali fanno parte di una section che è zero-ata all'avvio dell'applicazione.

    QUI puoi vedere il programma corretto e funzionante.
    Guardando lo stdout ottieni il mio stesso risultato,la printf non visualizza la parola piu lunga :/[/quote]

    Scusa, errore mio: ho incollato il codice sbagliato. Controlla ADESSO QUI

    Mancava anche l'inizializzazione della variabile lunghezza, altrimenti durante il loop di analisi del testo, lunghezza può valere qualunque.
  • Re: Esercizio stringhe C

    Grazie mille davvero,mi siete stati molto d'aiuto..Ora cerco di assimilare meglio i concetti aspettano che +m2+ mi dica se ha del materiale da cui studiare perche il mio libro lo trovo davvero povero di concetti
Devi accedere o registrarti per scrivere nel forum
15 risposte