Lista non riempita correttamente

di il
1 risposte

Lista non riempita correttamente

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

1 Risposte

  • Re: Lista non riempita correttamente

    Se a qualcuno può servire ho risolto.
    1- non bisogna assegnare la stringa nella newNode ma bisogna usare la strcpy/strdup
    2- non bisogna usare il break nell'if che controlla se la lista è vuota e si deve mettere il resto del codice fino a prima di parola=strtok(NULL,punt); dentro un else
Devi accedere o registrarti per scrivere nel forum
1 risposte