Help for my code

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • TC

    #1

    Help for my code

    Hi.
    I write a program in c language that read a text file and extrapolate
    the word. for all word the program calculate the number of the times
    that word is present in the text.
    The problem is the REALLOC that on my pc at times it produces error.
    Someone can help me for this error?
    Thank you


    /*Inclusione librerie*/
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <ctype.h>

    /*Definizione della strutura Elemento*/
    typedef struct
    {
    char *parola;
    unsigned int freq;
    }Elem;

    /*Definizione della lista delle parole trovate*/
    struct Albero
    {
    Elem Elemento;
    struct Albero *s;
    struct Albero *d;
    };

    /*Definizione variabili*/
    //Albero ordinato per alfabeto
    struct Albero *treeA = NULL;
    //Albero ordinato per frequenze
    struct Albero *treeF = NULL;

    unsigned int count = 0;

    /*Definizione funzioni*/
    //Funzione di scansione del file costruzione delle parole e chiamata
    //della funzione di inseriento nell'albero ordinato per alfabeto
    void Scansione(FILE *pf);
    //Aggiungi nodo all'albero ordinato per alfabeto
    struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola);
    //Stampa albero
    void Print(struct Albero *nodo);
    //Crea un nuovo albero ordinato per frequenza utilizzando come sorgente
    l'albero
    //ordinato per alfabeto
    void CreaAlberoF(str uct Albero *sorg);
    //Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
    valori dal
    //nodo passato come sorgente
    struct Albero * AggNodo_TreeF(s truct Albero *sorg, struct Albero *dest);


    main (void)
    {
    int fOK;
    //Nome del file di testo
    char *NF;
    //Puntatore al file
    FILE *pf;
    /*MAIN*/
    printf("\n Avvio del programma \n");

    do
    {
    printf("\nInser ire il nome del file di testo che si desidera
    utilizzare (Esempio: Testo.txt) \n");

    NF = (char*)malloc(s izeof (char));
    NF[0]='\0';

    do
    {
    scanf("%s",NF); //Lettura del nome del file
    }
    while (strlen(NF)<4);

    pf=fopen(NF, "r"); //Apertura del file in modalità di lettura

    //Controllo apertura del file
    if (pf==NULL)
    {
    //Restituzione del messaggio di errore in caso di mancata
    apertura
    perror("ERRORE nell'apertura del file");
    fOK = 0;
    }
    else
    {
    fOK = 1;
    }
    }while(fOK != 1);

    printf("\n\n");

    int iScelta = 0;

    do
    {
    /*Menù*/
    printf("\n 1- Scansione del file di testo \n");
    printf("\n 2- Creazione del file delle parole ordinato per
    frequenza \n");
    printf("\n 3- Stampa a video del file delle parole ordinato per
    frequenza \n");
    printf("\n 4- Stampa a video del file delle parole ordinato per
    ordine alfabetico \n");
    printf("\n 5- Esci \n");

    do
    {
    scanf("%d", &iScelta);
    }while(iScelta! = 1 && iScelta!= 2 && iScelta!= 3 && iScelta!= 4
    && iScelta!= 5);

    //Blocco di scelta
    switch(iScelta)
    {
    case (1):
    Scansione(pf);
    printf("\n Scansione EFFETTUATA! \n");
    break;
    case (2):
    CreaAlberoF(tre eA);
    printf("\n Lista delle parole ordinata per
    frequenza creata! \n");
    break;
    case (3):
    count=0;
    Print(treeF);
    break;
    case(4):
    count=0;
    Print(treeA) ;
    break;
    default:
    exit(0);
    }
    }while(iScelta! =5);
    }

    /*Funzione che effettua la scansione del file per individuare le parole
    e richiama la funzione di aggiunta di un nuovo elemento all'albero
    alfabeto*/
    void Scansione (FILE *pf)
    {
    char *parola; //Parola
    char c; //Variabile per la letura dei caratteri dal file di testo
    char *carattere; //Variabile utilizzatata per la concatenazione
    int lung; //Lunghezza della parola

    //Istanziazione e inizializzazion e della variabile carattere
    carattere = (char*)malloc(2 *sizeof(char));
    carattere[0]='\0';

    //Istanziazione e inizializzazion e della variabile parola
    //parola = (char*)malloc(1 *sizeof(char));
    // parola[0]='\0';

    while(!feof(pf) ) //Ripete fino alla fine del file
    {

    fread(&c,1*size of(char),1,pf); //Lettura del carattere
    printf("\n carattere letto->%c",c);
    //Controllo se il carattere è presente nell'alfabeto
    if (isalpha(c))
    {
    printf("\n carattere valido");
    //Calcolo della lunghezza della parola
    lung=strlen(par ola);
    //Assgnamento del valore alla variabile carattere
    carattere[0]=c;
    carattere[1]='\0';
    parola=(char*)r ealloc(parola,( lung+1)*sizeof( char));
    //lowercase
    *carattere = tolower(*caratt ere);
    //Concatenzazione dei caratteri per formare la parola
    parola = strcat(parola,c arattere);
    printf("\n valore attuale di parola->%s",parola);
    }
    else
    {
    //Inserimento della parola
    if ((parola[0]!='\0'))
    {
    //printf("%s",par ola);
    //Richiamo della funzione che aggiunge le parole
    nell'albero
    //ordianto per alfabeto
    if (treeA == NULL)
    {
    //Aggionamemto della radice
    treeA = AggNodo_TreeA(t reeA,parola);
    }
    else
    {
    AggNodo_TreeA(t reeA,parola);
    }
    //Reinizializzazi one della variabile parola
    //parola=NULL;
    parola=(char*)r ealloc(parola,s izeof(char));
    parola[0]='\0';
    }
    }
    }
    //Chiusura file
    fclose(pf);
    }

    //Funzione di aggiunta di un nodo all'albero
    struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola)
    {
    if (nodo == NULL)
    {
    //Creazione nuovo nodo dell'albero
    nodo = (struct Albero*) malloc(sizeof(s truct Albero));
    //Imposto il valore dei puntatori ai nodi figli
    nodo->d = NULL;
    nodo->s = NULL;
    //Impostazione della frequenza
    nodo->Elemento.fre q = 1;
    //Allocazione della memoria per la stringa contenete la parola
    if(!(nodo->Elemento.parol a =
    (char*)malloc(s trlen(parola)*s izeof(char))))
    {
    printf("\n Errore di allocazione della memoria.\n");
    }
    //Copia della stringa
    strcpy(nodo->Elemento.parol a,parola);
    //Se è il primo inserimento aggiorno il puntatore alla radice
    dell'albero
    printf("\n Parola inserita nel nodo: %s",nodo->Elemento.parol a);
    }
    else
    {
    //Variabile che restituisce il valore della comparazione parola
    int conf;
    //Comparazione della parola
    conf = strcmp(nodo->Elemento.parol a,parola);
    printf("\n S1: %s S2: %s Ris: %d",nodo->Elemento.parol a,parola,conf);
    //printf("%d",con f);

    switch(conf)
    {
    case (1):
    nodo->s = AggNodo_TreeA(n odo->s,parola);
    break;
    case (-1):
    nodo->d = AggNodo_TreeA(n odo->d,parola);
    break;
    default:
    //Se le parole sono uguali incremento il valore della
    frequenza
    nodo->Elemento.fre q = nodo->Elemento.fre q + 1 ;
    }
    }
    return nodo;
    }

    //Funzione di stampa dell'albero passato in input
    void Print(struct Albero *nodo)
    {

    if (nodo != NULL)
    {

    //Richiamo della funzione sul ramo sinistro
    Print(nodo->s);

    if (count == 10 )
    {
    printf("\n Premere un tasto per continuare...\n ");
    getchar();
    count = 0;
    }
    else
    {
    count++;
    }
    //Stampa della parola
    printf("\n PAROLA: %s ", nodo->Elemento.parol a);
    printf(" FREQUENZA: %d ", nodo->Elemento.freq) ;

    //Richiamo della funzione sul ramo destro
    Print(nodo->d);
    }
    }

    struct Albero * AggNodo_TreeF(s truct Albero *sorg, struct Albero *dest)
    {
    if (dest == NULL)
    {
    //Creazione nuovo nodo dell'albero
    dest = (struct Albero*) malloc(sizeof(s truct Albero));
    //Imposto il valore dei puntatori ai nodi figli
    dest->d = NULL;
    dest->s = NULL;
    //Impostazione della frequenza
    dest->Elemento.fre q = sorg->Elemento.fre q;
    //Allocazione della memoria per la stringa contenete la parola
    dest->Elemento.parol a =
    (char*)malloc(s izeof(sorg->Elemento.parol a));
    //Copia della stringa
    strcpy(dest->Elemento.parol a,sorg->Elemento.parol a);
    }
    else
    {
    //Comparazione Frequenza
    if ( dest->Elemento.fre q < sorg->Elemento.fre q)
    {
    dest->s = AggNodo_TreeF(s org,dest->s);
    }
    else
    {
    dest->d = AggNodo_TreeF(s org,dest->d);
    }
    }
    return dest;
    }

    /*Funzione che crea l'abero delle frequenze partendo dall'abero ordinato per
    alfabeto passato in input*/
    void CreaAlberoF(str uct Albero *sorg)
    {
    struct Albero *nodoprec;
    if (sorg != NULL)
    {
    CreaAlberoF(sor g->s);
    if (treeF == NULL)
    {
    treeF = AggNodo_TreeF(s org, treeF);
    }
    else
    {
    AggNodo_TreeF(s org, treeF);
    }
    CreaAlberoF(sor g->d);
    }
    }
  • AK

    #2
    Re: Help for my code


    TC wrote:[color=blue]
    > Hi.
    > I write a program in c language that read a text file and extrapolate
    > the word. for all word the program calculate the number of the times
    > that word is present in the text.
    > The problem is the REALLOC that on my pc at times it produces error.
    > Someone can help me for this error?
    > Thank you
    >
    >
    > /*Inclusione librerie*/
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    > #include <malloc.h>
    > #include <ctype.h>
    >
    > /*Definizione della strutura Elemento*/
    > typedef struct
    > {
    > char *parola;
    > unsigned int freq;
    > }Elem;
    >
    > /*Definizione della lista delle parole trovate*/
    > struct Albero
    > {
    > Elem Elemento;
    > struct Albero *s;
    > struct Albero *d;
    > };
    >
    > /*Definizione variabili*/
    > //Albero ordinato per alfabeto
    > struct Albero *treeA = NULL;
    > //Albero ordinato per frequenze
    > struct Albero *treeF = NULL;
    >
    > unsigned int count = 0;
    >
    > /*Definizione funzioni*/
    > //Funzione di scansione del file costruzione delle parole e chiamata
    > //della funzione di inseriento nell'albero ordinato per alfabeto
    > void Scansione(FILE *pf);
    > //Aggiungi nodo all'albero ordinato per alfabeto
    > struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola);
    > //Stampa albero
    > void Print(struct Albero *nodo);
    > //Crea un nuovo albero ordinato per frequenza utilizzando come sorgente
    > l'albero
    > //ordinato per alfabeto
    > void CreaAlberoF(str uct Albero *sorg);
    > //Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
    > valori dal
    > //nodo passato come sorgente
    > struct Albero * AggNodo_TreeF(s truct Albero *sorg, struct Albero *dest);
    >
    >
    > main (void)
    > {
    > int fOK;
    > //Nome del file di testo
    > char *NF;
    > //Puntatore al file
    > FILE *pf;
    > /*MAIN*/
    > printf("\n Avvio del programma \n");
    >
    > do
    > {
    > printf("\nInser ire il nome del file di testo che si desidera
    > utilizzare (Esempio: Testo.txt) \n");
    >
    > NF = (char*)malloc(s izeof (char));
    > NF[0]='\0';
    >
    > do
    > {
    > scanf("%s",NF); //Lettura del nome del file
    > }
    > while (strlen(NF)<4);
    >
    > pf=fopen(NF, "r"); //Apertura del file in modalità di lettura
    >
    > //Controllo apertura del file
    > if (pf==NULL)
    > {
    > //Restituzione del messaggio di errore in caso di mancata
    > apertura
    > perror("ERRORE nell'apertura del file");
    > fOK = 0;
    > }
    > else
    > {
    > fOK = 1;
    > }
    > }while(fOK != 1);
    >
    > printf("\n\n");
    >
    > int iScelta = 0;
    >
    > do
    > {
    > /*Menù*/
    > printf("\n 1- Scansione del file di testo \n");
    > printf("\n 2- Creazione del file delle parole ordinato per
    > frequenza \n");
    > printf("\n 3- Stampa a video del file delle parole ordinato per
    > frequenza \n");
    > printf("\n 4- Stampa a video del file delle parole ordinato per
    > ordine alfabetico \n");
    > printf("\n 5- Esci \n");
    >
    > do
    > {
    > scanf("%d", &iScelta);
    > }while(iScelta! = 1 && iScelta!= 2 && iScelta!= 3 && iScelta!= 4
    > && iScelta!= 5);
    >
    > //Blocco di scelta
    > switch(iScelta)
    > {
    > case (1):
    > Scansione(pf);
    > printf("\n Scansione EFFETTUATA! \n");
    > break;
    > case (2):
    > CreaAlberoF(tre eA);
    > printf("\n Lista delle parole ordinata per
    > frequenza creata! \n");
    > break;
    > case (3):
    > count=0;
    > Print(treeF);
    > break;
    > case(4):
    > count=0;
    > Print(treeA) ;
    > break;
    > default:
    > exit(0);
    > }
    > }while(iScelta! =5);
    > }
    >
    > /*Funzione che effettua la scansione del file per individuare le parole
    > e richiama la funzione di aggiunta di un nuovo elemento all'albero
    > alfabeto*/
    > void Scansione (FILE *pf)
    > {
    > char *parola; //Parola
    > char c; //Variabile per la letura dei caratteri dal file di testo
    > char *carattere; //Variabile utilizzatata per la concatenazione
    > int lung; //Lunghezza della parola
    >
    > //Istanziazione e inizializzazion e della variabile carattere
    > carattere = (char*)malloc(2 *sizeof(char));
    > carattere[0]='\0';
    >
    > //Istanziazione e inizializzazion e della variabile parola
    > //parola = (char*)malloc(1 *sizeof(char));
    > // parola[0]='\0';
    >
    > while(!feof(pf) ) //Ripete fino alla fine del file
    > {
    >
    > fread(&c,1*size of(char),1,pf); //Lettura del carattere
    > printf("\n carattere letto->%c",c);
    > //Controllo se il carattere è presente nell'alfabeto
    > if (isalpha(c))
    > {
    > printf("\n carattere valido");
    > //Calcolo della lunghezza della parola
    > lung=strlen(par ola);
    > //Assgnamento del valore alla variabile carattere
    > carattere[0]=c;
    > carattere[1]='\0';
    > parola=(char*)r ealloc(parola,( lung+1)*sizeof( char));
    > //lowercase
    > *carattere = tolower(*caratt ere);
    > //Concatenzazione dei caratteri per formare la parola
    > parola = strcat(parola,c arattere);
    > printf("\n valore attuale di parola->%s",parola);
    > }
    > else
    > {
    > //Inserimento della parola
    > if ((parola[0]!='\0'))
    > {
    > //printf("%s",par ola);
    > //Richiamo della funzione che aggiunge le parole
    > nell'albero
    > //ordianto per alfabeto
    > if (treeA == NULL)
    > {
    > //Aggionamemto della radice
    > treeA = AggNodo_TreeA(t reeA,parola);
    > }
    > else
    > {
    > AggNodo_TreeA(t reeA,parola);
    > }
    > //Reinizializzazi one della variabile parola
    > //parola=NULL;
    > parola=(char*)r ealloc(parola,s izeof(char));
    > parola[0]='\0';
    > }
    > }
    > }
    > //Chiusura file
    > fclose(pf);
    > }
    >
    > //Funzione di aggiunta di un nodo all'albero
    > struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola)
    > {
    > if (nodo == NULL)
    > {
    > //Creazione nuovo nodo dell'albero
    > nodo = (struct Albero*) malloc(sizeof(s truct Albero));
    > //Imposto il valore dei puntatori ai nodi figli
    > nodo->d = NULL;
    > nodo->s = NULL;
    > //Impostazione della frequenza
    > nodo->Elemento.fre q = 1;
    > //Allocazione della memoria per la stringa contenete la parola
    > if(!(nodo->Elemento.parol a =
    > (char*)malloc(s trlen(parola)*s izeof(char))))
    > {
    > printf("\n Errore di allocazione della memoria.\n");
    > }
    > //Copia della stringa
    > strcpy(nodo->Elemento.parol a,parola);
    > //Se è il primo inserimento aggiorno il puntatore alla radice
    > dell'albero
    > printf("\n Parola inserita nel nodo: %s",nodo->Elemento.parol a);
    > }
    > else
    > {
    > //Variabile che restituisce il valore della comparazione parola
    > int conf;
    > //Comparazione della parola
    > conf = strcmp(nodo->Elemento.parol a,parola);
    > printf("\n S1: %s S2: %s Ris: %d",nodo->Elemento.parol a,parola,conf);
    > //printf("%d",con f);
    >
    > switch(conf)
    > {
    > case (1):
    > nodo->s = AggNodo_TreeA(n odo->s,parola);
    > break;
    > case (-1):
    > nodo->d = AggNodo_TreeA(n odo->d,parola);
    > break;
    > default:
    > //Se le parole sono uguali incremento il valore della
    > frequenza
    > nodo->Elemento.fre q = nodo->Elemento.fre q + 1 ;
    > }
    > }
    > return nodo;
    > }
    >
    > //Funzione di stampa dell'albero passato in input
    > void Print(struct Albero *nodo)
    > {
    >
    > if (nodo != NULL)
    > {
    >
    > //Richiamo della funzione sul ramo sinistro
    > Print(nodo->s);
    >
    > if (count == 10 )
    > {
    > printf("\n Premere un tasto per continuare...\n ");
    > getchar();
    > count = 0;
    > }
    > else
    > {
    > count++;
    > }
    > //Stampa della parola
    > printf("\n PAROLA: %s ", nodo->Elemento.parol a);
    > printf(" FREQUENZA: %d ", nodo->Elemento.freq) ;
    >
    > //Richiamo della funzione sul ramo destro
    > Print(nodo->d);
    > }
    > }
    >
    > struct Albero * AggNodo_TreeF(s truct Albero *sorg, struct Albero *dest)
    > {
    > if (dest == NULL)
    > {
    > //Creazione nuovo nodo dell'albero
    > dest = (struct Albero*) malloc(sizeof(s truct Albero));
    > //Imposto il valore dei puntatori ai nodi figli
    > dest->d = NULL;
    > dest->s = NULL;
    > //Impostazione della frequenza
    > dest->Elemento.fre q = sorg->Elemento.fre q;
    > //Allocazione della memoria per la stringa contenete la parola
    > dest->Elemento.parol a =
    > (char*)malloc(s izeof(sorg->Elemento.parol a));
    > //Copia della stringa
    > strcpy(dest->Elemento.parol a,sorg->Elemento.parol a);
    > }
    > else
    > {
    > //Comparazione Frequenza
    > if ( dest->Elemento.fre q < sorg->Elemento.fre q)
    > {
    > dest->s = AggNodo_TreeF(s org,dest->s);
    > }
    > else
    > {
    > dest->d = AggNodo_TreeF(s org,dest->d);
    > }
    > }
    > return dest;
    > }
    >
    > /*Funzione che crea l'abero delle frequenze partendo dall'abero ordinato per
    > alfabeto passato in input*/
    > void CreaAlberoF(str uct Albero *sorg)
    > {
    > struct Albero *nodoprec;
    > if (sorg != NULL)
    > {
    > CreaAlberoF(sor g->s);
    > if (treeF == NULL)
    > {
    > treeF = AggNodo_TreeF(s org, treeF);
    > }
    > else
    > {
    > AggNodo_TreeF(s org, treeF);
    > }
    > CreaAlberoF(sor g->d);
    > }
    > }[/color]

    Please translate your comments in English would you?

    Comment

    • Ingo Menger

      #3
      Re: Help for my code


      TC schrieb:
      [color=blue]
      > //Allocazione della memoria per la stringa contenete la parola
      > dest->Elemento.parol a = (char*)malloc(s izeof(sorg->Elemento.parol a));
      > //Copia della stringa
      > strcpy(dest->Elemento.parol a,sorg->Elemento.parol a);[/color]

      How many memory is allocated here?
      What will the value of the expression sizeof(sorg->Elemento.parol a) be?
      Che cosa quando la parola esta molto lungo?

      Comment

      • Ingo Menger

        #4
        Re: Help for my code


        AK schrieb:
        [color=blue]
        > Please translate your comments in English would you?[/color]

        Not needed. Not all people here are barbarians :)
        FYI, "funzione" might be, ahh well, a function.
        If you have no clue of roman languages, the code should tell you, that
        "abero" must be a tree.
        And so forth.

        Comment

        • Flash Gordon

          #5
          Re: Help for my code

          TC wrote:[color=blue]
          > Hi.
          > I write a program in c language that read a text file and extrapolate
          > the word. for all word the program calculate the number of the times
          > that word is present in the text.
          > The problem is the REALLOC that on my pc at times it produces error.
          > Someone can help me for this error?
          > Thank you
          >
          >
          > /*Inclusione librerie*/
          > #include <stdio.h>
          > #include <string.h>
          > #include <stdlib.h>
          > #include <malloc.h>[/color]

          This is not a standard header. The correct header for malloc and friends
          is stdlib.h, so I suggest getting rid of whatever documentation you've
          got that suggests using malloc.h
          [color=blue]
          > #include <ctype.h>
          >
          > /*Definizione della strutura Elemento*/
          > typedef struct
          > {
          > char *parola;
          > unsigned int freq;
          > }Elem;
          >
          > /*Definizione della lista delle parole trovate*/
          > struct Albero
          > {
          > Elem Elemento;
          > struct Albero *s;
          > struct Albero *d;
          > };
          >
          > /*Definizione variabili*/
          > //Albero ordinato per alfabeto[/color]

          // style comments are not valid in C89, which is the only standard most
          compilers implement fully. Also, they do not survive line wrapping so
          even when using C99 (which does support them) they are inadvisable for
          postings to Usenet.
          [color=blue]
          > struct Albero *treeA = NULL;
          > //Albero ordinato per frequenze
          > struct Albero *treeF = NULL;
          >
          > unsigned int count = 0;
          >
          > /*Definizione funzioni*/
          > //Funzione di scansione del file costruzione delle parole e chiamata
          > //della funzione di inseriento nell'albero ordinato per alfabeto
          > void Scansione(FILE *pf);
          > //Aggiungi nodo all'albero ordinato per alfabeto
          > struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola);
          > //Stampa albero
          > void Print(struct Albero *nodo);
          > //Crea un nuovo albero ordinato per frequenza utilizzando come sorgente
          > l'albero
          > //ordinato per alfabeto
          > void CreaAlberoF(str uct Albero *sorg);
          > //Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
          > valori dal[/color]

          See what I mean about // style comments being a pain on Usenet?
          [color=blue]
          > //nodo passato come sorgente
          > struct Albero * AggNodo_TreeF(s truct Albero *sorg, struct Albero *dest);
          >
          >
          > main (void)
          > {
          > int fOK;
          > //Nome del file di testo
          > char *NF;[/color]

          Please don't use all upper case names for variables. By convention all
          upper case names are only used for macros and possibly the constants
          defined by an enum.
          [color=blue]
          > //Puntatore al file
          > FILE *pf;
          > /*MAIN*/
          > printf("\n Avvio del programma \n");
          >
          > do
          > {
          > printf("\nInser ire il nome del file di testo che si desidera
          > utilizzare (Esempio: Testo.txt) \n");
          >
          > NF = (char*)malloc(s izeof (char));[/color]

          Don't cast the return value of malloc. In fact, don't cast EVER unless
          you know EXACTLY why the cast is required. The compiler complaining at
          you is NOT a valid reason for casting, it means you need to find out WHY
          the compiler is complaining.

          Note, I'm not saying don't ever use a cast, sometimes they are required,
          only that you should not use them UNLESS you know why it is required and
          what effect it will have.

          The generally preferred form for using malloc around here is:
          NF = malloc(N * sizeof *NF);
          where N is the number of items you want NF to point to. However, in your
          case NF is a char pointer, so with N=1 (as in your case) this allocate
          enough space for exactly ONE character. Since all strings are terminated
          by a nul character, this means there is only enough space for an empty
          string.

          Also check the return value, malloc CAN fail.
          [color=blue]
          > NF[0]='\0';
          >
          > do
          > {
          > scanf("%s",NF); //Lettura del nome del file[/color]

          Don't EVER use %s in scanf, always specify the maximum number of
          characters to be read. In any case, as stated above, the space pointed
          to by NF is not large enough for ANY non-empty string, and scanf won't
          change that.

          In any case, you would be best using a fixed length array and fgets, but
          remember to check the return value of fgets (as you should have done
          with scanf) and also note what fgets does if the line is too long and
          what it does if the line fits.
          [color=blue]
          > }
          > while (strlen(NF)<4);[/color]

          That, IMHO, is a stupid check. I regularly use files named t or t.t when
          I want to create a file for testing purposes.
          [color=blue]
          > pf=fopen(NF, "r"); //Apertura del file in modalità di lettura
          >
          > //Controllo apertura del file
          > if (pf==NULL)
          > {
          > //Restituzione del messaggio di errore in caso di mancata
          > apertura
          > perror("ERRORE nell'apertura del file");
          > fOK = 0;
          > }
          > else
          > {
          > fOK = 1;
          > }
          > }while(fOK != 1);[/color]

          That is a bad habit. In general any non-zero value is treated as true in C.
          } while (!fOK);
          [color=blue]
          > printf("\n\n");
          >
          > int iScelta = 0;
          >
          > do
          > {
          > /*Menù*/
          > printf("\n 1- Scansione del file di testo \n");
          > printf("\n 2- Creazione del file delle parole ordinato per
          > frequenza \n");
          > printf("\n 3- Stampa a video del file delle parole ordinato per
          > frequenza \n");
          > printf("\n 4- Stampa a video del file delle parole ordinato per
          > ordine alfabetico \n");
          > printf("\n 5- Esci \n");[/color]

          You might as well use puts, although there is nothing technically wrong
          with printf here.
          [color=blue]
          > do
          > {
          > scanf("%d", &iScelta);[/color]

          Check the return value of scanf. Also, read up on what will happen if
          the user enters something other than a number.
          [color=blue]
          > }while(iScelta! = 1 && iScelta!= 2 && iScelta!= 3 && iScelta!= 4
          > && iScelta!= 5);
          >
          > //Blocco di scelta
          > switch(iScelta)
          > {
          > case (1):
          > Scansione(pf);
          > printf("\n Scansione EFFETTUATA! \n");
          > break;
          > case (2):
          > CreaAlberoF(tre eA);
          > printf("\n Lista delle parole ordinata per frequenza
          > creata! \n");
          > break;
          > case (3):
          > count=0;
          > Print(treeF);
          > break;
          > case(4):
          > count=0;
          > Print(treeA) ;
          > break;
          > default:
          > exit(0);
          > }
          > }while(iScelta! =5);
          > }
          >
          > /*Funzione che effettua la scansione del file per individuare le parole
          > e richiama la funzione di aggiunta di un nuovo elemento all'albero
          > alfabeto*/
          > void Scansione (FILE *pf)
          > {
          > char *parola; //Parola[/color]

          What is the point of a comment that just restates the name of a variable?
          [color=blue]
          > char c; //Variabile per la letura dei caratteri dal file di testo
          > char *carattere; //Variabile utilizzatata per la concatenazione
          > int lung; //Lunghezza della parola
          >
          > //Istanziazione e inizializzazion e della variabile carattere
          > carattere = (char*)malloc(2 *sizeof(char));[/color]

          See previous comments about malloc usage. Also, sizeof(char) is 1 by
          definition. This applies even if a char is 324857324985739 3485 bits long.
          [color=blue]
          > carattere[0]='\0';
          >
          > //Istanziazione e inizializzazion e della variabile parola
          > //parola = (char*)malloc(1 *sizeof(char));
          > // parola[0]='\0';[/color]

          Why is the above commented out? It is the only initialisation for this
          variable. Also see previous comments about malloc.
          [color=blue]
          > while(!feof(pf) ) //Ripete fino alla fine del file
          > {
          >
          > fread(&c,1*size of(char),1,pf); //Lettura del carattere[/color]

          Using fread for a single character is just plain daft, as is not
          checking the return value. You should use getc or fgetc and ALWAYS check
          whether the input function succeeded. Remember that feof does not
          predict the future, it only tell you AFTER a read has failed due to
          reaching the end of a file.
          [color=blue]
          > printf("\n carattere letto->%c",c);
          > //Controllo se il carattere è presente nell'alfabeto
          > if (isalpha(c))
          > {
          > printf("\n carattere valido");
          > //Calcolo della lunghezza della parola
          > lung=strlen(par ola);[/color]

          Unless I've missed something, parola is uninitialised the first time you
          get here, so this invokes undefined behaviour. On some systems under
          some conditions this *will* crash your program. Unless, of course, you
          uncomment the code that initialises it.
          [color=blue]
          > //Assgnamento del valore alla variabile carattere
          > carattere[0]=c;
          > carattere[1]='\0';
          > parola=(char*)r ealloc(parola,( lung+1)*sizeof( char));[/color]

          This is very bad usage of realloc, see comments about malloc and also
          look up on what realloc does if it fails. You need a temporary variable
          and, once again, to check the return value.

          I've got bored with all the errors, but that should be enough to keep
          you busy.

          <snip remainder of code>
          --
          Flash Gordon
          Living in interesting times.
          Although my email address says spam, it is real and I read it.

          Comment

          • TC

            #6
            Re: Help for my code

            I have make some corrections, but the program doesn't correctly work.
            Help me please.

            /*Inclusione librerie*/
            #include <stdio.h>
            #include <string.h>
            #include <stdlib.h>
            #include <malloc.h>

            /*Definizione della strutura Elemento*/
            typedef struct
            {
            char *parola;
            unsigned int freq;
            }Elem;

            /*Definizione della lista delle parole trovate*/
            struct Albero
            {
            Elem Elemento;
            struct Albero *s;
            struct Albero *d;
            };

            /*Definizione variabili*/
            //Albero ordinato per alfabeto
            struct Albero *treeA = NULL;
            //Albero ordinato per frequenze
            struct Albero *treeF = NULL;

            unsigned int count = 0;

            /*Definizione funzioni*/
            //Funzione di scansione del file costruzione delle parole e chiamata
            //della funzione di inseriento nell'albero ordinato per alfabeto
            void Scansione(FILE *pf);
            //Aggiungi nodo all'albero ordinato per alfabeto
            struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola);
            //Stampa albero
            void Print(struct Albero *nodo);
            //Crea un nuovo albero ordinato per frequenza utilizzando come sorgente
            l'albero
            //ordinato per alfabeto
            void CreaAlberoF(str uct Albero *sorg);
            //Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
            valori dal
            //nodo passato come sorgente
            struct Albero * AggNodo_TreeF(s truct Albero *sorg, struct Albero *dest);


            main (void)
            {
            char scelta;
            int fOK;
            //Nome del file di testo
            char nf[50];
            //Puntatore al file
            FILE *pf;
            /*MAIN*/
            printf("\n Avvio del programma \n");

            do
            {
            fOK = 0;
            printf("\nInser ire il nome del file di testo che si desidera
            utilizzare (Esempio: Testo.txt) \n");

            gets(nf); //Lettura del nome del file

            pf=fopen(nf,"r" ); //Apertura del file in modalità di lettura

            //Controllo apertura del file
            if (pf==NULL)
            {
            //Restituzione del messaggio di errore in caso di mancata apertura
            perror("ERRORE nell'apertura del file");
            fOK = 1;
            }

            }while(fOK != 0);

            printf("\n\n");



            do
            {
            scelta = 0;
            /*Menù*/
            printf("\n 1- Scansione del file di testo \n");
            printf("\n 2- Creazione del file delle parole ordinato per frequenza \n");
            printf("\n 3- Stampa a video del file delle parole ordinato per
            frequenza \n");
            printf("\n 4- Stampa a video del file delle parole ordinato per ordine
            alfabetico \n");
            printf("\n 5- Esci \n");

            do
            {
            scelta = getchar();
            }while(scelta!= '1' && scelta!= '2' && scelta!= '3' && scelta!= '4' &&
            scelta!= '5');
            count=0;
            //Blocco di scelta
            switch(scelta)
            {
            case ('1'):
            Scansione(pf);
            printf("\n Scansione EFFETTUATA! \n");
            break;
            case ('2'):
            CreaAlberoF(tre eA);
            printf("\n Lista delle parole ordinata per frequenza creata! \n");
            break;
            case ('3'):
            Print(treeF);
            break;
            case('4'):
            Print(treeA) ;
            break;
            default:
            exit(0);
            }
            }while(scelta!= 5);
            }

            /*Funzione che effettua la scansione del file per individuare le parole
            e richiama la funzione di aggiunta di un nuovo elemento all'albero
            alfabeto*/
            void Scansione (FILE *pf)
            {
            char *ptr;
            char *parola;
            char c; //Variabile per la letura dei caratteri dal file di testo
            char *carattere; //Variabile utilizzatata per la concatenazione
            int lung; //Lunghezza della parola

            //Istanziazione e inizializzazion e della variabile carattere
            carattere = malloc(2*sizeof (char));
            carattere[0]='\0';

            //Istanziazione e inizializzazion e della variabile parola
            parola = malloc(1*sizeof (parola));
            parola[0]='\0';

            while(!feof(pf) ) //Ripete fino alla fine del file
            {
            c = fgetc(pf);//Lettura del carattere
            //printf("\n carattere letto->%c",c);
            //Controllo se il carattere è presente nell'alfabeto
            if (isalpha(c))
            {
            //printf("\n carattere valido");
            //Calcolo della lunghezza della parola
            lung=strlen(par ola);

            //Assgnamento del valore alla variabile carattere
            carattere[0]=c;
            carattere[1]='\0';
            //printf("\nLungh ezza parola: %d",lung);

            if(!(parola= realloc(parola, (lung+1)*sizeof (char))))
            {
            printf("\n REALLOC : Errore di allocazione della
            memoria.\n");
            getch();
            }
            //lowercase
            *carattere = tolower(*caratt ere);
            //Concatenzazione dei caratteri per formare la parola
            parola = strcat(parola,c arattere);
            //printf("\n valore attuale di parola->%s",parola);
            }
            else
            {
            //Inserimento della parola
            if ((parola[0]!='\0'))
            {
            printf("\n PAROLA: -> %s",parola);
            //Richiamo della funzione che aggiunge le parole nell'albero
            //ordianto per alfabeto
            if (treeA == NULL)
            {
            //Aggionamemto della radice
            treeA = AggNodo_TreeA(t reeA,parola);
            }
            else
            {
            AggNodo_TreeA(t reeA,parola);
            }
            //Reinizializzazi one della variabile parola
            parola= realloc(parola, sizeof(char));
            parola[0]='\0';
            }
            }
            }
            //Chiusura file
            fclose(pf);
            }

            //Funzione di aggiunta di un nodo all'albero
            struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola)
            {

            if (nodo == NULL)
            {
            //Creazione nuovo nodo dell'albero
            if(!(nodo = (struct Albero*) malloc(sizeof(s truct Albero))))
            {
            printf("\n Errore di allocazione della memoria.\n");
            }
            //Imposto il valore dei puntatori ai nodi figli
            nodo->d = NULL;
            nodo->s = NULL;
            //Impostazione della frequenza
            nodo->Elemento.fre q = 1;

            //Allocazione della memoria per la stringa contenete la parola
            *nodo->Elemento.parol a = malloc(sizeof(p arola));
            if(nodo->Elemento.parol a == NULL)
            {
            printf("\n Errore di allocazione della memoria.\n");
            }
            //Copia della stringa
            strcpy(nodo->Elemento.parol a,parola);
            //Se è il primo inserimento aggiorno il puntatore alla radice dell'albero
            //printf("\n Parola inserita nel nodo: %s",nodo->Elemento.parol a);
            //getch();
            }
            else
            {
            //Variabile che restituisce il valore della comparazione parola
            int conf;
            //Comparazione della parola
            conf = strcmp(nodo->Elemento.parol a,parola);
            //printf("\n S1: %s S2: %s Ris: %d",nodo->Elemento.parol a,parola,conf);

            switch(conf)
            {
            case (1):
            nodo->s = AggNodo_TreeA(n odo->s,parola);
            break;
            case (-1):
            nodo->d = AggNodo_TreeA(n odo->d,parola);
            break;
            default:
            //Se le parole sono uguali incremento il valore della frequenza
            nodo->Elemento.fre q = nodo->Elemento.fre q + 1 ;
            break;
            }
            }
            return nodo;
            }

            //Funzione di stampa dell'albero passato in input
            void Print(struct Albero *nodo)
            {

            if (nodo != NULL)
            {

            //Richiamo della funzione sul ramo sinistro
            Print(nodo->s);

            if (count == 10 )
            {
            printf("\n Premere un tasto per continuare...\n ");
            getchar();
            count = 0;
            }
            else
            {
            count++;
            }
            //Stampa della parola
            printf("\n PAROLA: %s ", nodo->Elemento.parol a);
            printf(" FREQUENZA: %d ", nodo->Elemento.freq) ;

            //Richiamo della funzione sul ramo destro
            Print(nodo->d);
            }
            }

            struct Albero * AggNodo_TreeF(s truct Albero *sorg, struct Albero *dest)
            {
            if (dest == NULL)
            {
            //Creazione nuovo nodo dell'albero
            dest = (struct Albero*) malloc(sizeof(s truct Albero));
            //Imposto il valore dei puntatori ai nodi figli
            dest->d = NULL;
            dest->s = NULL;
            //Impostazione della frequenza
            dest->Elemento.fre q = sorg->Elemento.fre q;
            //Allocazione della memoria per la stringa contenete la parola
            dest->Elemento.parol a = malloc(sizeof(s org->Elemento.parol a));
            //Copia della stringa
            strcpy(dest->Elemento.parol a,sorg->Elemento.parol a);
            }
            else
            {
            //Comparazione Frequenza
            if ( dest->Elemento.fre q < sorg->Elemento.fre q)
            {
            dest->s = AggNodo_TreeF(s org,dest->s);
            }
            else
            {
            dest->d = AggNodo_TreeF(s org,dest->d);
            }
            }
            return dest;
            }

            /*Funzione che crea l'abero delle frequenze partendo dall'abero ordinato
            per
            alfabeto passato in input*/
            void CreaAlberoF(str uct Albero *sorg)
            {
            struct Albero *nodoprec;
            if (sorg != NULL)
            {
            CreaAlberoF(sor g->s);
            if (treeF == NULL)
            {
            treeF = AggNodo_TreeF(s org, treeF);
            }
            else
            {
            AggNodo_TreeF(s org, treeF);
            }
            CreaAlberoF(sor g->d);
            }
            }

            Comment

            • Flash Gordon

              #7
              Re: Help for my code

              TC wrote:[color=blue]
              > I have make some corrections, but the program doesn't correctly work.
              > Help me please.[/color]

              Help us. In future tell us what you mean by "not working".
              [color=blue]
              > /*Inclusione librerie*/
              > #include <stdio.h>
              > #include <string.h>
              > #include <stdlib.h>
              > #include <malloc.h>[/color]

              malloc.h is STILL not a standard header, so don't include it. stdlib.h
              which you are now also including provides all you need in terms of
              malloc and friends.
              [color=blue]
              > /*Definizione della strutura Elemento*/
              > typedef struct
              > {
              > char *parola;
              > unsigned int freq;
              > }Elem;
              >
              > /*Definizione della lista delle parole trovate*/
              > struct Albero
              > {
              > Elem Elemento;
              > struct Albero *s;
              > struct Albero *d;
              > };
              >
              > /*Definizione variabili*/
              > //Albero ordinato per alfabeto
              > struct Albero *treeA = NULL;
              > //Albero ordinato per frequenze
              > struct Albero *treeF = NULL;
              >
              > unsigned int count = 0;
              >
              > /*Definizione funzioni*/
              > //Funzione di scansione del file costruzione delle parole e chiamata
              > //della funzione di inseriento nell'albero ordinato per alfabeto
              > void Scansione(FILE *pf);
              > //Aggiungi nodo all'albero ordinato per alfabeto
              > struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola);
              > //Stampa albero
              > void Print(struct Albero *nodo);
              > //Crea un nuovo albero ordinato per frequenza utilizzando come sorgente
              > l'albero[/color]

              You are still using // style comments. Please don't for the reasons I
              previously posted, including the fact that as you can see above they
              BREAK because of line wrapping.
              [color=blue]
              > //ordinato per alfabeto
              > void CreaAlberoF(str uct Albero *sorg);
              > //Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
              > valori dal
              > //nodo passato come sorgente
              > struct Albero * AggNodo_TreeF(s truct Albero *sorg, struct Albero *dest);
              >
              >
              > main (void)
              > {
              > char scelta;
              > int fOK;
              > //Nome del file di testo
              > char nf[50];
              > //Puntatore al file
              > FILE *pf;
              > /*MAIN*/
              > printf("\n Avvio del programma \n");
              >
              > do
              > {
              > fOK = 0;
              > printf("\nInser ire il nome del file di testo che si desidera
              > utilizzare (Esempio: Testo.txt) \n");
              >
              > gets(nf); //Lettura del nome del file[/color]

              Don't use gets. If the line is too long this WILL overflow the buffer
              and can lead to ANYTHING happening. Use fgets but check the return value
              and also check for the \n at the end of the text read (if it is not
              there the line was too long to fit in the buffer.
              [color=blue]
              > pf=fopen(nf,"r" ); //Apertura del file in modalità di lettura
              >
              > //Controllo apertura del file
              > if (pf==NULL)
              > {
              > //Restituzione del messaggio di errore in caso di mancata
              > apertura
              > perror("ERRORE nell'apertura del file");
              > fOK = 1;
              > }
              >
              > }while(fOK != 0);
              >
              > printf("\n\n");
              >
              >
              >
              > do
              > {
              > scelta = 0;
              > /*Menù*/
              > printf("\n 1- Scansione del file di testo \n");
              > printf("\n 2- Creazione del file delle parole ordinato per
              > frequenza \n");
              > printf("\n 3- Stampa a video del file delle parole ordinato per
              > frequenza \n");
              > printf("\n 4- Stampa a video del file delle parole ordinato per
              > ordine alfabetico \n");
              > printf("\n 5- Esci \n");
              >
              > do
              > {
              > scelta = getchar();
              > }while(scelta!= '1' && scelta!= '2' && scelta!= '3' && scelta!=
              > '4' && scelta!= '5');[/color]

              Better. However, for the future please note that on many systems no
              input is passed to your program until the user presses enter. Telling
              the user to select an option and press enter is a way around this, then
              you can read all the characters up to and including the enter.
              [color=blue]
              > count=0;
              > //Blocco di scelta
              > switch(scelta)
              > {
              > case ('1'):
              > Scansione(pf);
              > printf("\n Scansione EFFETTUATA! \n");
              > break;
              > case ('2'):
              > CreaAlberoF(tre eA);
              > printf("\n Lista delle parole ordinata per frequenza
              > creata! \n");
              > break;
              > case ('3'):
              > Print(treeF);
              > break;
              > case('4'):
              > Print(treeA) ;
              > break;
              > default:
              > exit(0);
              > }
              > }while(scelta!= 5);
              > }
              >
              > /*Funzione che effettua la scansione del file per individuare le parole
              > e richiama la funzione di aggiunta di un nuovo elemento all'albero
              > alfabeto*/
              > void Scansione (FILE *pf)
              > {
              > char *ptr;
              > char *parola;
              > char c; //Variabile per la letura dei caratteri dal file di testo
              > char *carattere; //Variabile utilizzatata per la concatenazione
              > int lung; //Lunghezza della parola
              >
              > //Istanziazione e inizializzazion e della variabile carattere
              > carattere = malloc(2*sizeof (char));[/color]

              Better, but multiplying by sizeof(char) is pointless as it is defined as
              being 1. Also, what if malloc fails?
              [color=blue]
              > carattere[0]='\0';
              >
              > //Istanziazione e inizializzazion e della variabile parola
              > parola = malloc(1*sizeof (parola));
              > parola[0]='\0';
              >
              > while(!feof(pf) ) //Ripete fino alla fine del file[/color]

              Check the comp.lang.c FAQ. feof tells you if you reached the end of a
              file when you tried doing the read, i.e. this is too early to do this check.
              [color=blue]
              > {
              > c = fgetc(pf);//Lettura del carattere[/color]

              You need to check for feof here instead. You also need to check for it
              failing for other reasons.
              [color=blue]
              > //printf("\n carattere letto->%c",c);
              > //Controllo se il carattere è presente nell'alfabeto
              > if (isalpha(c))
              > {
              > //printf("\n carattere valido");
              > //Calcolo della lunghezza della parola
              > lung=strlen(par ola);
              >
              > //Assgnamento del valore alla variabile carattere
              > carattere[0]=c;
              > carattere[1]='\0';
              > //printf("\nLungh ezza parola: %d",lung);
              >
              > if(!(parola= realloc(parola, (lung+1)*sizeof (char))))
              > {[/color]

              If the realloc failed, then the old buffer (which you have just lost
              your only pointer to) is still allocated. So you need to use a temporary
              pointer.
              [color=blue]
              > printf("\n REALLOC : Errore di allocazione della
              > memoria.\n");
              > getch();[/color]

              getch is not a standard function. Also, if the realloc failed shouldn't
              you abort this function (and possibly the program in this case) rather
              than continuing on and using the pointer which now does not point
              anywhere valid?
              [color=blue]
              > }
              > //lowercase
              > *carattere = tolower(*caratt ere);
              > //Concatenzazione dei caratteri per formare la parola
              > parola = strcat(parola,c arattere);
              > //printf("\n valore attuale di parola->%s",parola);
              > }
              > else
              > {
              > //Inserimento della parola
              > if ((parola[0]!='\0'))
              > {
              > printf("\n PAROLA: -> %s",parola);
              > //Richiamo della funzione che aggiunge le parole
              > nell'albero
              > //ordianto per alfabeto
              > if (treeA == NULL)
              > {
              > //Aggionamemto della radice
              > treeA = AggNodo_TreeA(t reeA,parola);
              > }
              > else
              > {
              > AggNodo_TreeA(t reeA,parola);[/color]

              Don't you need the pointer you have just thrown away? This is probably
              the cause of the problem you had spotted.
              [color=blue]
              > }
              > //Reinizializzazi one della variabile parola
              > parola= realloc(parola, sizeof(char));[/color]

              See previous comment about realloc.
              [color=blue]
              > parola[0]='\0';
              > }
              > }
              > }
              > //Chiusura file
              > fclose(pf);
              > }
              >
              > //Funzione di aggiunta di un nodo all'albero
              > struct Albero *AggNodo_TreeA( struct Albero *nodo, char *parola)
              > {
              >
              > if (nodo == NULL)
              > {
              > //Creazione nuovo nodo dell'albero
              > if(!(nodo = (struct Albero*) malloc(sizeof(s truct Albero))))
              > {
              > printf("\n Errore di allocazione della memoria.\n");
              > }
              > //Imposto il valore dei puntatori ai nodi figli
              > nodo->d = NULL;
              > nodo->s = NULL;
              > //Impostazione della frequenza
              > nodo->Elemento.fre q = 1;
              >
              > //Allocazione della memoria per la stringa contenete la parola
              > *nodo->Elemento.parol a = malloc(sizeof(p arola));[/color]


              This is also WRONG. You need to allocate enough space for the string you
              are about to copy in, NOT enough for a pointer to a string.
              [color=blue]
              > if(nodo->Elemento.parol a == NULL)
              > {
              > printf("\n Errore di allocazione della memoria.\n");
              > }[/color]

              Again, if the allocation failed you don't want to continue on and make
              use of the null pointer as if it was a valid pointer.

              <snip>

              I've not checked the rest of your program.
              --
              Flash Gordon
              Living in interesting times.
              Although my email address says spam, it is real and I read it.

              Comment

              Working...