Pagina 1 di 1

contatore lettere in c[SOLVED]

Inviato: mar 30 giu 2009, 23:20
da Blallo
devo fare un semplice programma che calcoli quante parole che iniziano per una data lettera e stampare a video per ogni lettera il risultato, ma quando eseguo mi da segmentation fault

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#define MAXSTR 80
#define ALPHA 26

int main()
{
	FILE *fp;
	int i, c, b, a[ALPHA]={0};
	char str1[MAXSTR];

	printf("Inserire nome file:");
	scanf("%s", &str1);

	if((fp=fopen(str1,"r"))==NULL)
	{
		fprintf(stderr,"Errore apertura file");
		return EXIT_FAILURE;
	}

	c=' ';
	while((b=fgetc(fp))!=EOF)
	{
		if(isalpha(b) && !isalpha(c))
			a[toupper(b)-'A']++;
		c=b;
	}

	for(i=0; i<ALPHA; i++)
		printf("Parole che iniziano con %s, %d\n", i+'A', a[i]);

	fclose(fp);
	return EXIT_SUCCESS;
}	

Re: contatore lettere in c

Inviato: mar 30 giu 2009, 23:27
da Blallo
chiedo scusa a tutti, semplice errore di scrittura :D

Codice: Seleziona tutto

   for(i=0; i<ALPHA; i++)
      printf("Parole che iniziano con %c, %d\n", i+'A', a[i]);
ora funziona...(bastava sostituire %s con %c
al massimo mi sapete dire un algoritmo più efficiente?

Re: contatore lettere in c

Inviato: mer 1 lug 2009, 9:13
da Vito
Ho fatto queste cose a gennaio ed in questo momento non mi ricordo proprio niente.... :lol: :lol: :lol: (sarà perchè sono immerso in un altro esame...)

Re: contatore lettere in c

Inviato: mer 1 lug 2009, 9:18
da ulisse89
Anchio le ho fatte a gennaio e in effetti stanno cominciando a passare di mente. Comunque io ti proporrei: all'inizio dichiari un vettore di stringhe, (ovvero di vettori di caratteri), poi l'unica cosa che ti posso dire è usare la fscanf che direttamente mangia una stringa fino all primo spazio che incontra, guardi se il primo carattere è la lettera, e se lo è, la metti nel vettore di stringhe.

Re: contatore lettere in c

Inviato: mer 1 lug 2009, 11:09
da GioPower
Non ricordo bene quali funzioni il C metta a disposizione per lavorare su stringhe, ma idealmente si potrebbe fare cosi':
1) Apri il file con fopen.
2) Vai alla fine del file con fseek, ricavi la dimensione del file con ftell, e torni all'inizio del file con fseek.
3) Fai una malloc della dimensione del file e leggi tutto il file (non carattere per carattere) con fread (credo) usando lo spazio appena allocato.
4) Chiudi il file con fclose.
5) Analizzi la stringa letta al passo 3. Idealmente devi trovare tutte le ricorrenze della lettera in questione che sia preceduta da uno spazio o un "a capo" (/n) o e' la prima lettera della stringa. E' possibile che ci siano altri caratteri da controllare oltre agli spazi o \n, come le parentisi.
6) Fine. Magari fai una free sullo spazio allocato al passo 3.

Devi stare attento ad allocare la giusta quantita' di memoria al passo 3 e a non uscire dalle dimensioni del vettore con l'indice del ciclo al passo 5 (per esempio richiedere il carattere in posizione -1 oppure oltre alla dimensione della malloc fatta).
Inoltre, se del codice uno funziona, ti consiglio di inserire dei puts("UNASTRINGAATUASCELTA") in mezzo al codice per capire dove il programma si ferma e individuare meglio il problema. Oppure usa una debugger, ma non mi pare il caso.

Ciao e buona fortuna.

Re: contatore lettere in c

Inviato: mer 1 lug 2009, 22:43
da Blallo
GioPower ha scritto:Non ricordo bene quali funzioni il C metta a disposizione per lavorare su stringhe, ma idealmente si potrebbe fare cosi':
1) Apri il file con fopen.
2) Vai alla fine del file con fseek, ricavi la dimensione del file con ftell, e torni all'inizio del file con fseek.
3) Fai una malloc della dimensione del file e leggi tutto il file (non carattere per carattere) con fread (credo) usando lo spazio appena allocato.
4) Chiudi il file con fclose.
5) Analizzi la stringa letta al passo 3. Idealmente devi trovare tutte le ricorrenze della lettera in questione che sia preceduta da uno spazio o un "a capo" (/n) o e' la prima lettera della stringa. E' possibile che ci siano altri caratteri da controllare oltre agli spazi o \n, come le parentisi.
6) Fine. Magari fai una free sullo spazio allocato al passo 3.

Devi stare attento ad allocare la giusta quantita' di memoria al passo 3 e a non uscire dalle dimensioni del vettore con l'indice del ciclo al passo 5 (per esempio richiedere il carattere in posizione -1 oppure oltre alla dimensione della malloc fatta).
Inoltre, se del codice uno funziona, ti consiglio di inserire dei puts("UNASTRINGAATUASCELTA") in mezzo al codice per capire dove il programma si ferma e individuare meglio il problema. Oppure usa una debugger, ma non mi pare il caso.

Ciao e buona fortuna.
wow...lo proverò tra un po..appena capirò che hai scritto :D (devo studiarmi le operazioni che si muovono sul file ancora)

Re: contatore lettere in c

Inviato: mer 1 lug 2009, 23:07
da targzeta
Lascia perdere, non è una gran bella soluzione:
  • perchè aprire il file, poi spostarsi in fondo e poi fare un ftell per sapere quanto è grande? c'è la funzione stat che ritorna le informazioni sul file, tra cui anche la dimensione in byte.
  • perchè leggersi un intero file in memoria per scandirlo carattere per carattere solo una volta? E se il file è grande 1GB, ci allochiamo 1GB di memoria?
Tutto questo è solo una mia opinione, ovviamente,
Emanuele

Re: contatore lettere in c

Inviato: gio 2 lug 2009, 10:16
da GioPower
spina ha scritto:perchè aprire il file, poi spostarsi in fondo e poi fare un ftell per sapere quanto è grande? c'è la funzione stat che ritorna le informazioni sul file, tra cui anche la dimensione in byte.
Non mi ricordo molto le funzioni del C per maneggiare i file. Forse usare ftell e fseek per ricavare le dimensioni di un file era l'esercizio per imparare ad usare le funzioni. :-k
spina ha scritto:perchè leggersi un intero file in memoria per scandirlo carattere per carattere solo una volta? E se il file è grande 1GB, ci allochiamo 1GB di memoria?
Ma qui si puo fare un po' come si vuole, se ti fidi di come gestisce il disco il tuo disco e il tuo s.o. si puo' leggere carattere per carattere.
Altriementi puoi leggere tutto il file in un botto (se serve e si puo', anche un 1GB), naturalemente se ti aspetti file da 4GB, lo si puo leggere a blocchi magari dei MB a volta ed elaborarli, ma non mi sembrava il caso di complicare troppo le cose in questo contesto.
Ma forse non ha neache senso fare questa cosa per un file piccolo e per quello che jimmy ha da fare. :-k