Ciao a tutti!
Sto iniziando a programmare in C e sto avendo problemi con la gestione delle liste. Il programma seguente, in particolare, non funziona.
Lo scopo è semplicemente prendere le parole da un file e contare le occorrenze di ciascuna parola. Bisogna poi riempire il file di output con le righe che contengono 'parola' 'frequenza'.
Concettualmente tutto molto semplice ma il codice non funziona (abbiate pazienza ma è il mio primo esercizio con le liste).
Cercando di debuggare ho visto che legge le parole troncate (nonostante la strtok faccia correttamente il proprio lavoro) e non riempie la lista correttamente. Vi posto il codice nella speranza che qualcuno possa aiutarmi.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_DIM 1000
typedef struct node *link;
struct node {
char *name; //ricorda che devo anche allocarti
int frequency;
link next;
};
link readFile(char *str);
void outputFile(char *str, link h);
link listInsHead(link h, char *name, int f);
link newNode(char *name, int f, link next);
int main() {
link h;
h=readFile("01in.txt");
outputFile("01out.txt",h);
return 0;
}
link readFile(char *str){ //passo alla funzione il puntatore alla testa della lista
FILE *fp;
fp=fopen(str,"r");
if(fp==NULL){
printf("Errore nell'apertura del file di input");
exit(-2);
}
char row[MAX_DIM+1];
char *parola,*parolaInList;
char punt[12]={' ','\n',',','.',';',':','-','_','"','!','(',')'};
int flag;
link x,h;
h=NULL;
//voglio leggere tutte le righe del file e mettere tutte le stringhe in una lista
//voglio anche aggiornare la frequenza delle parole
while(fgets(row,MAX_DIM+1,fp)!=NULL){
parola=strtok(row,punt);
while(parola!=NULL){
flag=0;
if(h==NULL){
h=listInsHead(h,parola,1);
parolaInList=h->name;
break;
}
//ora scorro la lista e controllo se parola è già presente nella lista
for(x=h;x!=NULL;x=x->next){
if(strcasecmp(x->name,parola)==0){
x->frequency++;
parolaInList=x->name;
flag=1;
break;
}
}
//se il flag è zero vuol dire che non sono al primo nodo e non ho trovato la parola nella lista
//vuol dire che devo aggiungere la parola letta alla lista
if(flag==0){
h=listInsHead(h,parola,1);
// parolaInList=x->name;
}
//ora aggiorno la condizione sulla parola per non andare in loop
parola=strtok(NULL,punt);
}
}
// scorri la lista e stampa per controllo
printf("Stampo la lista per controllo: \n");
int i;
for(x=h, i=0;x!=NULL;x=x->next, i++){
printf("elemento %d: %s %d\n", i, x->name,x->frequency);
}
fclose(fp);
return h;
}
void outputFile(char *str, link h){
FILE *fp;
fp=fopen(str,"w");
if(fp==NULL){
printf("Errore nell'apertura del file di output");
exit(-3);
}
link x;
//scorro la lista e stampo su file
for(x=h; x!=NULL;x=x->next){
fprintf(fp,"%s %d\n",x->name,x->frequency);
}
fclose(fp);
}
link newNode(char *name, int f, link next){
link x=malloc(sizeof *x);
if(x==NULL) {
printf("Allocation error");
return NULL;
}
else {
x->name=(char*)malloc((strlen(name)+1)*sizeof(char));
x->name=name;
x->frequency=f;
x->next=next;
}
return x;
}
link listInsHead(link h, char *name, int f){
h=newNode(name,f,h);
return h;
}
}
Il file che sto cercando di scorrere contiene semplicemente le stringhe:
Mi illumino di immenso
Illumino di immenso
Di immenso
IMMENSO
ma quando stampo l'output di prova ottengo questo:
Stampo la lista per controllo:
elemento 0: immenso 3
elemento 1: o 1
elemento 2: IMMENSO 3