Esercizio per contare cartteri, spazi ecc in C
Ragazzi sto facendo quest esercizio e non riesco a capire perchè il compilatore all'esecuzione del programma mi dà errore. Per favore mi poete aiutare a capire dove sbaglio???
#include<stdio.h> #define MAX 100 int main(){ int spazi=0,cifre=0, lettere=0, newline=0, acar=0; //acar sta per altri caratteri int i, j, a; char testo[MAX], c; printf("Inserire il testo\n"); for(j=0;(c=getchar()) < MAX; j++){ testo[j] = c; } while(testo[i] != '\0'){ if(testo[i]>=48 && testo[i]<=57) cifre++; else if((testo[i]>=65 && testo[i]<=90)||(testo[i]>=97 && testo[i]<=122)) lettere++; else if(testo[i] == 10) newline++; else if(testo[i] == 0) spazi++; else if((testo[i]>=33 && testo[i]<=47) ||(testo[i]>=91 && testo[i]<=96)) acar++; } printf("Il numero di spazi e': %d", spazi); printf("Il numero di newline e': %d", newline); printf("Il numero di lettere e': %d", lettere); printf("Il numero di cifre e': %d", cifre); printf("Il numero di altri caratteri e': %d", acar); return 0; }
Risposte
Quale errore?
Prova con la stringa 'abcd' e dimmi cosa succede.
Prova con la stringa 'abcd' e dimmi cosa succede.
non appena inserisco la stringa abcd......il compilatore va in crash e mi esce dal programma.....
Non capisco che cosa speri di ottenere esattamente usando il seguente codice.. (c = getchar()) sarà maggiore o uguale a MAX=100 per ogni carattere minuscolo dopo 'd' (usando l'ASCII), e non vedo in che modo questa sarebbe una buona condizione per terminare la lettura di una stringa da standard input.
Nel successivo ciclo:
i non è inizializzata prima di entrare del ciclo e potrebbe avere qualsiasi valore (causando quindi potenzialmente un crash del programma).
Per il resto, sbagli tutto riguardo all'uso dell'ASCII. Non c'è infatti nessuna garanzia che un compilatore in C utilizzi la codifica ASCII. È in effetti molto probabile nei sistemi mainstream, ma non esiste alcuna garanzia. Usare direttamente i codici ASCII è quindi una pessima idea. Un'idea un po' migliore sarebbe quella di usare costanti come 'a' e 'Z'.. ma anche in questo caso il risultato non è corretto per quanto riguarda la nostra lingua. Quale dovrebbe ad esempio essere secondo te il numero di minuscole nella stringa "perché"? Come ho già avuto modo di dire in un post recente, l'UNICO modo per scrivere correttamente questo genere di programmi è facendo uso delle funzioni della libreria ctype.h (e anche usandola si potrebbero avere dei problemi). Ma questo è dovuto a disinformazione e non ad un errore da parte tua.
printf("Inserire il testo\n"); for(j=0; (c=getchar()) < MAX; j++) { testo[j] = c; }
Nel successivo ciclo:
while(testo[i] != '\0'){ /* ... */ }
i non è inizializzata prima di entrare del ciclo e potrebbe avere qualsiasi valore (causando quindi potenzialmente un crash del programma).
Per il resto, sbagli tutto riguardo all'uso dell'ASCII. Non c'è infatti nessuna garanzia che un compilatore in C utilizzi la codifica ASCII. È in effetti molto probabile nei sistemi mainstream, ma non esiste alcuna garanzia. Usare direttamente i codici ASCII è quindi una pessima idea. Un'idea un po' migliore sarebbe quella di usare costanti come 'a' e 'Z'.. ma anche in questo caso il risultato non è corretto per quanto riguarda la nostra lingua. Quale dovrebbe ad esempio essere secondo te il numero di minuscole nella stringa "perché"? Come ho già avuto modo di dire in un post recente, l'UNICO modo per scrivere correttamente questo genere di programmi è facendo uso delle funzioni della libreria ctype.h (e anche usandola si potrebbero avere dei problemi). Ma questo è dovuto a disinformazione e non ad un errore da parte tua.
Per esempio il nostro professore non ci ha mai parlato di una libreria ctype.h....anzi è stato lui che ci ha consigliato di usare questo tipo di approccio. Comunque per quanto rigurada
printf("Inserire il testo\n");
for(j=0; (c=getchar()) < MAX; j++)
{
testo[j] = c;
}
ho preso esempio da un libro..però forse ho errato nel modo di compresndere il testo.....comunque ora riprovo a riguardare meglio gli appunti....però se c'è qualche consiglio che mi volete dare, lo accetto volentieri...
printf("Inserire il testo\n");
for(j=0; (c=getchar()) < MAX; j++)
{
testo[j] = c;
}
ho preso esempio da un libro..però forse ho errato nel modo di compresndere il testo.....comunque ora riprovo a riguardare meglio gli appunti....però se c'è qualche consiglio che mi volete dare, lo accetto volentieri...
Quando dovrebbe fermarsi la lettura della stringa? Al primo spazio? Alla fine della riga? Quando un particolare carattere viene premuto?
Per esempio se al posto di MAX ci metto che deve essere != '\0'.....non si dovrebbe fermare alla fine della stringa???
E se la riga avesse più di 100 caratteri? Andresti oltre ai limiti del tuo array.. Hai davvero bisogno di una stringa? Riesci a trovare un modo di "unire" i due cicli?
Io dubito che il professore te l'abbia suggerito così. A parte i commenti di apatriarca sull'uso della libreria ctype.h che continua ad essere l'unico modo sufficientemente portabile per lavorare con le lettere ci sono dei problemi nella gestione dei cicli e anche qualche problema nella comprensione di quando una variabile esiste e quando non esiste.
Sotto c'é la versione messa a posto ma cerca di capire (a parte la chiamata alle funzioni di ctype.h) il perché il tuo era assolutamente sbagliato nella creazione del ciclo. Questo codice prende esattamente 100 caratteri.
Per portarlo a un numero meno fisso si può fare così:
Sotto c'é la versione messa a posto ma cerca di capire (a parte la chiamata alle funzioni di ctype.h) il perché il tuo era assolutamente sbagliato nella creazione del ciclo. Questo codice prende esattamente 100 caratteri.
#include<stdio.h> #include<ctype.h> #define MAX 100 int main(void) { int spazi=0, cifre=0, lettere=0, newline=0, acar=0; int i, j, a; char testo[MAX], c; printf("Inserire il testo\n"); for(j=0; j < MAX; j++) { c = getchar(); if(isdigit(c)) ++cifre; else if(isalpha(c)) ++lettere; else if(c == '\n') ++newline; else if(ispace(c)) ++spazi; else ++acar; } printf("Il numero di spazi e': %d", spazi); printf("Il numero di newline e': %d", newline); printf("Il numero di lettere e': %d", lettere); printf("Il numero di cifre e': %d", cifre); printf("Il numero di altri caratteri e': %d", acar); return 0; }
Per portarlo a un numero meno fisso si può fare così:
for(j=0; ((c=getchar())!= '\0')&&(j < MAX); j++)