kwb
26-08-2010, 16:07
Ciao, avevo tempo fa questo programma da fare: dato un file con del testo dentro, stampare a schermo quante volte compare ogni lettera. Per i caratteri speciali e punteggiatura, usare un'unico contatore. Le lettere maiuscole e minuscole sono contate separatamente.
La soluzione proposta dal professore era quella di fare 2 array, i primi due da 26 caratteri per i contatori di tutte le lettere dell'alfabeto, una variabile per contenere gli 'altri caratteri' e un grande array bello lungo per contenere la stringa in input ( dal file ).
Ovviamente char_low[0] corrisponde ad a, char_low[3] corrisponde a d ecc...
Avevo già svolto questo esercizio facendo uno switch sulla stringa in input, analizzando ogni singola parola e incrementando di uno la posizione dell'array corrispondente al carattere.
Come si capisce, facendo lo switch, viene un lavoro lunghissimo per una banalità di programma.
Ho pensato a come farlo in altro modo, ma non ho niente in mente... Mi pare impossibile ci sia solo questa dispendiosa soluzione ( che tra l'altro non so quanto sia leggera a livello di codice... ).
Questo era quello che avevo scritto:
/*Write a C program that reads a text from a file and prints how many times each character has
occurred in the text read. Upper and lower case letters should be counted separately. Use a
single counter to compute the number of occurrences of all the characters other than letters and
digits. Hint: use an array of counters for lowercase characters, where index 0 stands for ëaí,
index 1 for ëbí and so on. A similar array can be used for uppercase characters.*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 200
int main()
{
int c_low [25];
int c_up [25];
int i;
int c_ot=0;
FILE *fp;
int d;
char txt[MAX];
for (i=0;i<25;i++)
{
c_low[i]=0;
c_up[i]=0;
}
if((fp=fopen("troppo_gaggi.txt","r"))==NULL)
printf("error\n");
else
{
while((fgets(txt, MAX-1, fp)!=NULL))
{
for(i=0;txt[i]!=NULL;i++)
switch(txt[i])
{
case 'a':
c_low[0]++;
break;
case'b':
c_low[1]++;
break;
case'c':
c_low[2]++;
break;
case'd':
c_low[3]++;
break;
case'e':
c_low[4]++;
break;
case'f':
c_low[5]++;
break;
case'g':
c_low[6]++;
break;
case'h':
c_low[7]++;
break;
case'i':
c_low[8]++;
break;
case'j':
c_low[9]++;
break;
case'k':
c_low[10]++;
break;
case'l':
c_low[11]++;
break;
case'm':
c_low[12]++;
break;
case'n':
c_low[13]++;
break;
case'o':
c_low[14]++;
break;
case'p':
c_low[15]++;
break;
case'q':
c_low[16]++;
break;
case'r':
c_low[17]++;
break;
case's':
c_low[18]++;
break;
case't':
c_low[19]++;
break;
case'u':
c_low[20]++;
break;
case'v':
c_low[21]++;
break;
case'w':
c_low[22]++;
break;
case'x':
c_low[23]++;
break;
case'y':
c_low[24]++;
break;
case'z':
c_low[25]++;
break;
case'A':
c_up[0]++;
break;
case'B':
c_up[1]++;
break;
case'C':
c_up[2]++;
break;
case'D':
c_up[3]++;
break;
case'E':
c_up[4]++;
break;
case'F':
c_up[5]++;
break;
case'G':
c_up[6]++;
break;
case'H':
c_up[7]++;
break;
case'I':
c_up[8]++;
break;
case'J':
c_up[9]++;
break;
case'K':
c_up[10]++;
break;
case'L':
c_up[11]++;
break;
case'M':
c_up[12]++;
break;
case'N':
c_up[13]++;
break;
case'O':
c_up[14]++;
break;
case'P':
c_up[15]++;
break;
case'Q':
c_up[16]++;
break;
case'R':
c_up[17]++;
break;
case'S':
c_up[18]++;
break;
case'T':
c_up[19]++;
break;
case'U':
c_up[20]++;
break;
case'V':
c_up[21]++;
break;
case'W':
c_up[22]++;
break;
case'X':
c_up[23]++;
break;
case'Y':
c_up[24]++;
break;
case'Z':
c_up[25]++;
break;
default:
c_ot++;
break;
}
}
}
fclose(fp);
for (i = 0; i <25; i++)
{
printf("c_low[%d] = %d\n", i, c_low[i]);
printf("c_up[%d] = %d\n", i, c_up[i]);
}
printf("Other characters: %d\n", c_ot);
return 0;
}
Vorrei rifarlo senza perdere troppo tempo visto che mi manca. Essenzialmente ho capito come funziona, ero curioso di capire se si poteva fare in altro modo, più corto.
Ho provato a guardare anche nella libreria ctype.h ma non c'è niente che faccia al caso mio...
EDIT: Ho visto che su alcuni libri di programmazione utilizzano, per la risoluzione di questo esercizio, gli argomenti nel main argv[] e robe simili che non ho la più pallida idea a cosa servano xD
La soluzione proposta dal professore era quella di fare 2 array, i primi due da 26 caratteri per i contatori di tutte le lettere dell'alfabeto, una variabile per contenere gli 'altri caratteri' e un grande array bello lungo per contenere la stringa in input ( dal file ).
Ovviamente char_low[0] corrisponde ad a, char_low[3] corrisponde a d ecc...
Avevo già svolto questo esercizio facendo uno switch sulla stringa in input, analizzando ogni singola parola e incrementando di uno la posizione dell'array corrispondente al carattere.
Come si capisce, facendo lo switch, viene un lavoro lunghissimo per una banalità di programma.
Ho pensato a come farlo in altro modo, ma non ho niente in mente... Mi pare impossibile ci sia solo questa dispendiosa soluzione ( che tra l'altro non so quanto sia leggera a livello di codice... ).
Questo era quello che avevo scritto:
/*Write a C program that reads a text from a file and prints how many times each character has
occurred in the text read. Upper and lower case letters should be counted separately. Use a
single counter to compute the number of occurrences of all the characters other than letters and
digits. Hint: use an array of counters for lowercase characters, where index 0 stands for ëaí,
index 1 for ëbí and so on. A similar array can be used for uppercase characters.*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 200
int main()
{
int c_low [25];
int c_up [25];
int i;
int c_ot=0;
FILE *fp;
int d;
char txt[MAX];
for (i=0;i<25;i++)
{
c_low[i]=0;
c_up[i]=0;
}
if((fp=fopen("troppo_gaggi.txt","r"))==NULL)
printf("error\n");
else
{
while((fgets(txt, MAX-1, fp)!=NULL))
{
for(i=0;txt[i]!=NULL;i++)
switch(txt[i])
{
case 'a':
c_low[0]++;
break;
case'b':
c_low[1]++;
break;
case'c':
c_low[2]++;
break;
case'd':
c_low[3]++;
break;
case'e':
c_low[4]++;
break;
case'f':
c_low[5]++;
break;
case'g':
c_low[6]++;
break;
case'h':
c_low[7]++;
break;
case'i':
c_low[8]++;
break;
case'j':
c_low[9]++;
break;
case'k':
c_low[10]++;
break;
case'l':
c_low[11]++;
break;
case'm':
c_low[12]++;
break;
case'n':
c_low[13]++;
break;
case'o':
c_low[14]++;
break;
case'p':
c_low[15]++;
break;
case'q':
c_low[16]++;
break;
case'r':
c_low[17]++;
break;
case's':
c_low[18]++;
break;
case't':
c_low[19]++;
break;
case'u':
c_low[20]++;
break;
case'v':
c_low[21]++;
break;
case'w':
c_low[22]++;
break;
case'x':
c_low[23]++;
break;
case'y':
c_low[24]++;
break;
case'z':
c_low[25]++;
break;
case'A':
c_up[0]++;
break;
case'B':
c_up[1]++;
break;
case'C':
c_up[2]++;
break;
case'D':
c_up[3]++;
break;
case'E':
c_up[4]++;
break;
case'F':
c_up[5]++;
break;
case'G':
c_up[6]++;
break;
case'H':
c_up[7]++;
break;
case'I':
c_up[8]++;
break;
case'J':
c_up[9]++;
break;
case'K':
c_up[10]++;
break;
case'L':
c_up[11]++;
break;
case'M':
c_up[12]++;
break;
case'N':
c_up[13]++;
break;
case'O':
c_up[14]++;
break;
case'P':
c_up[15]++;
break;
case'Q':
c_up[16]++;
break;
case'R':
c_up[17]++;
break;
case'S':
c_up[18]++;
break;
case'T':
c_up[19]++;
break;
case'U':
c_up[20]++;
break;
case'V':
c_up[21]++;
break;
case'W':
c_up[22]++;
break;
case'X':
c_up[23]++;
break;
case'Y':
c_up[24]++;
break;
case'Z':
c_up[25]++;
break;
default:
c_ot++;
break;
}
}
}
fclose(fp);
for (i = 0; i <25; i++)
{
printf("c_low[%d] = %d\n", i, c_low[i]);
printf("c_up[%d] = %d\n", i, c_up[i]);
}
printf("Other characters: %d\n", c_ot);
return 0;
}
Vorrei rifarlo senza perdere troppo tempo visto che mi manca. Essenzialmente ho capito come funziona, ero curioso di capire se si poteva fare in altro modo, più corto.
Ho provato a guardare anche nella libreria ctype.h ma non c'è niente che faccia al caso mio...
EDIT: Ho visto che su alcuni libri di programmazione utilizzano, per la risoluzione di questo esercizio, gli argomenti nel main argv[] e robe simili che non ho la più pallida idea a cosa servano xD