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(struct Albero *sorg);
//Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
valori dal
//nodo passato come sorgente
struct Albero * AggNodo_TreeF(struct 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("\nInserire il nome del file di testo che si desidera
utilizzare (Esempio: Testo.txt) \n");
NF = (char*)malloc(sizeof (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(treeA);
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 inizializzazione della variabile carattere
carattere = (char*)malloc(2*sizeof(char));
carattere[0]='\0';
//Istanziazione e inizializzazione della variabile parola
//parola = (char*)malloc(1*sizeof(char));
// parola[0]='\0';
while(!feof(pf)) //Ripete fino alla fine del file
{
fread(&c,1*sizeof(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(parola);
//Assgnamento del valore alla variabile carattere
carattere[0]=c;
carattere[1]='\0';
parola=(char*)realloc(parola,(lung+1)*sizeof(char) );
//lowercase
*carattere = tolower(*carattere);
//Concatenzazione dei caratteri per formare la parola
parola = strcat(parola,carattere);
printf("\n valore attuale di parola->%s",parola);
}
else
{
//Inserimento della parola
if ((parola[0]!='\0'))
{
//printf("%s",parola);
//Richiamo della funzione che aggiunge le parole
nell'albero
//ordianto per alfabeto
if (treeA == NULL)
{
//Aggionamemto della radice
treeA = AggNodo_TreeA(treeA,parola);
}
else
{
AggNodo_TreeA(treeA,parola);
}
//Reinizializzazione della variabile parola
//parola=NULL;
parola=(char*)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
nodo = (struct Albero*) malloc(sizeof(struct Albero));
//Imposto il valore dei puntatori ai nodi figli
nodo->d = NULL;
nodo->s = NULL;
//Impostazione della frequenza
nodo->Elemento.freq = 1;
//Allocazione della memoria per la stringa contenete la parola
if(!(nodo->Elemento.parola =
(char*)malloc(strlen(parola)*sizeof(char))))
{
printf("\n Errore di allocazione della memoria.\n");
}
//Copia della stringa
strcpy(nodo->Elemento.parola,parola);
//Se è il primo inserimento aggiorno il puntatore alla radice
dell'albero
printf("\n Parola inserita nel nodo: %s",nodo->Elemento.parola);
}
else
{
//Variabile che restituisce il valore della comparazione parola
int conf;
//Comparazione della parola
conf = strcmp(nodo->Elemento.parola,parola);
printf("\n S1: %s S2: %s Ris: %d",nodo->Elemento.parola,parola,conf);
//printf("%d",conf);
switch(conf)
{
case (1):
nodo->s = AggNodo_TreeA(nodo->s,parola);
break;
case (-1):
nodo->d = AggNodo_TreeA(nodo->d,parola);
break;
default:
//Se le parole sono uguali incremento il valore della
frequenza
nodo->Elemento.freq = nodo->Elemento.freq + 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.parola);
printf(" FREQUENZA: %d ", nodo->Elemento.freq);
//Richiamo della funzione sul ramo destro
Print(nodo->d);
}
}
struct Albero * AggNodo_TreeF(struct Albero *sorg, struct Albero *dest)
{
if (dest == NULL)
{
//Creazione nuovo nodo dell'albero
dest = (struct Albero*) malloc(sizeof(struct Albero));
//Imposto il valore dei puntatori ai nodi figli
dest->d = NULL;
dest->s = NULL;
//Impostazione della frequenza
dest->Elemento.freq = sorg->Elemento.freq;
//Allocazione della memoria per la stringa contenete la parola
dest->Elemento.parola =
(char*)malloc(sizeof(sorg->Elemento.parola));
//Copia della stringa
strcpy(dest->Elemento.parola,sorg->Elemento.parola);
}
else
{
//Comparazione Frequenza
if ( dest->Elemento.freq < sorg->Elemento.freq)
{
dest->s = AggNodo_TreeF(sorg,dest->s);
}
else
{
dest->d = AggNodo_TreeF(sorg,dest->d);
}
}
return dest;
}
/*Funzione che crea l'abero delle frequenze partendo dall'abero ordinato per
alfabeto passato in input*/
void CreaAlberoF(struct Albero *sorg)
{
struct Albero *nodoprec;
if (sorg != NULL)
{
CreaAlberoF(sorg->s);
if (treeF == NULL)
{
treeF = AggNodo_TreeF(sorg, treeF);
}
else
{
AggNodo_TreeF(sorg, treeF);
}
CreaAlberoF(sorg->d);
}
} | | | | 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(struct Albero *sorg);
> //Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
> valori dal
> //nodo passato come sorgente
> struct Albero * AggNodo_TreeF(struct 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("\nInserire il nome del file di testo che si desidera
> utilizzare (Esempio: Testo.txt) \n");
>
> NF = (char*)malloc(sizeof (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(treeA);
> 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 inizializzazione della variabile carattere
> carattere = (char*)malloc(2*sizeof(char));
> carattere[0]='\0';
>
> //Istanziazione e inizializzazione della variabile parola
> //parola = (char*)malloc(1*sizeof(char));
> // parola[0]='\0';
>
> while(!feof(pf)) //Ripete fino alla fine del file
> {
>
> fread(&c,1*sizeof(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(parola);
> //Assgnamento del valore alla variabile carattere
> carattere[0]=c;
> carattere[1]='\0';
> parola=(char*)realloc(parola,(lung+1)*sizeof(char) );
> //lowercase
> *carattere = tolower(*carattere);
> //Concatenzazione dei caratteri per formare la parola
> parola = strcat(parola,carattere);
> printf("\n valore attuale di parola->%s",parola);
> }
> else
> {
> //Inserimento della parola
> if ((parola[0]!='\0'))
> {
> //printf("%s",parola);
> //Richiamo della funzione che aggiunge le parole
> nell'albero
> //ordianto per alfabeto
> if (treeA == NULL)
> {
> //Aggionamemto della radice
> treeA = AggNodo_TreeA(treeA,parola);
> }
> else
> {
> AggNodo_TreeA(treeA,parola);
> }
> //Reinizializzazione della variabile parola
> //parola=NULL;
> parola=(char*)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
> nodo = (struct Albero*) malloc(sizeof(struct Albero));
> //Imposto il valore dei puntatori ai nodi figli
> nodo->d = NULL;
> nodo->s = NULL;
> //Impostazione della frequenza
> nodo->Elemento.freq = 1;
> //Allocazione della memoria per la stringa contenete la parola
> if(!(nodo->Elemento.parola =
> (char*)malloc(strlen(parola)*sizeof(char))))
> {
> printf("\n Errore di allocazione della memoria.\n");
> }
> //Copia della stringa
> strcpy(nodo->Elemento.parola,parola);
> //Se è il primo inserimento aggiorno il puntatore alla radice
> dell'albero
> printf("\n Parola inserita nel nodo: %s",nodo->Elemento.parola);
> }
> else
> {
> //Variabile che restituisce il valore della comparazione parola
> int conf;
> //Comparazione della parola
> conf = strcmp(nodo->Elemento.parola,parola);
> printf("\n S1: %s S2: %s Ris: %d",nodo->Elemento.parola,parola,conf);
> //printf("%d",conf);
>
> switch(conf)
> {
> case (1):
> nodo->s = AggNodo_TreeA(nodo->s,parola);
> break;
> case (-1):
> nodo->d = AggNodo_TreeA(nodo->d,parola);
> break;
> default:
> //Se le parole sono uguali incremento il valore della
> frequenza
> nodo->Elemento.freq = nodo->Elemento.freq + 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.parola);
> printf(" FREQUENZA: %d ", nodo->Elemento.freq);
>
> //Richiamo della funzione sul ramo destro
> Print(nodo->d);
> }
> }
>
> struct Albero * AggNodo_TreeF(struct Albero *sorg, struct Albero *dest)
> {
> if (dest == NULL)
> {
> //Creazione nuovo nodo dell'albero
> dest = (struct Albero*) malloc(sizeof(struct Albero));
> //Imposto il valore dei puntatori ai nodi figli
> dest->d = NULL;
> dest->s = NULL;
> //Impostazione della frequenza
> dest->Elemento.freq = sorg->Elemento.freq;
> //Allocazione della memoria per la stringa contenete la parola
> dest->Elemento.parola =
> (char*)malloc(sizeof(sorg->Elemento.parola));
> //Copia della stringa
> strcpy(dest->Elemento.parola,sorg->Elemento.parola);
> }
> else
> {
> //Comparazione Frequenza
> if ( dest->Elemento.freq < sorg->Elemento.freq)
> {
> dest->s = AggNodo_TreeF(sorg,dest->s);
> }
> else
> {
> dest->d = AggNodo_TreeF(sorg,dest->d);
> }
> }
> return dest;
> }
>
> /*Funzione che crea l'abero delle frequenze partendo dall'abero ordinato per
> alfabeto passato in input*/
> void CreaAlberoF(struct Albero *sorg)
> {
> struct Albero *nodoprec;
> if (sorg != NULL)
> {
> CreaAlberoF(sorg->s);
> if (treeF == NULL)
> {
> treeF = AggNodo_TreeF(sorg, treeF);
> }
> else
> {
> AggNodo_TreeF(sorg, treeF);
> }
> CreaAlberoF(sorg->d);
> }
> }[/color]
Please translate your comments in English would you? | | | | re: Help for my code
TC schrieb:
[color=blue]
> //Allocazione della memoria per la stringa contenete la parola
> dest->Elemento.parola = (char*)malloc(sizeof(sorg->Elemento.parola));
> //Copia della stringa
> strcpy(dest->Elemento.parola,sorg->Elemento.parola);[/color]
How many memory is allocated here?
What will the value of the expression sizeof(sorg->Elemento.parola) be?
Che cosa quando la parola esta molto lungo? | | | | 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. | | | | 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(struct 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(struct 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("\nInserire il nome del file di testo che si desidera
> utilizzare (Esempio: Testo.txt) \n");
>
> NF = (char*)malloc(sizeof (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(treeA);
> 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 inizializzazione 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 3248573249857393485 bits long.
[color=blue]
> carattere[0]='\0';
>
> //Istanziazione e inizializzazione 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*sizeof(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(parola);[/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*)realloc(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. | | | | 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(struct Albero *sorg);
//Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
valori dal
//nodo passato come sorgente
struct Albero * AggNodo_TreeF(struct 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("\nInserire 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(treeA);
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 inizializzazione della variabile carattere
carattere = malloc(2*sizeof(char));
carattere[0]='\0';
//Istanziazione e inizializzazione 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(parola);
//Assgnamento del valore alla variabile carattere
carattere[0]=c;
carattere[1]='\0';
//printf("\nLunghezza parola: %d",lung);
if(!(parola= realloc(parola,(lung+1)*sizeof(char))))
{
printf("\n REALLOC : Errore di allocazione della
memoria.\n");
getch();
}
//lowercase
*carattere = tolower(*carattere);
//Concatenzazione dei caratteri per formare la parola
parola = strcat(parola,carattere);
//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(treeA,parola);
}
else
{
AggNodo_TreeA(treeA,parola);
}
//Reinizializzazione 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(struct 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.freq = 1;
//Allocazione della memoria per la stringa contenete la parola
*nodo->Elemento.parola = malloc(sizeof(parola));
if(nodo->Elemento.parola == NULL)
{
printf("\n Errore di allocazione della memoria.\n");
}
//Copia della stringa
strcpy(nodo->Elemento.parola,parola);
//Se è il primo inserimento aggiorno il puntatore alla radice dell'albero
//printf("\n Parola inserita nel nodo: %s",nodo->Elemento.parola);
//getch();
}
else
{
//Variabile che restituisce il valore della comparazione parola
int conf;
//Comparazione della parola
conf = strcmp(nodo->Elemento.parola,parola);
//printf("\n S1: %s S2: %s Ris: %d",nodo->Elemento.parola,parola,conf);
switch(conf)
{
case (1):
nodo->s = AggNodo_TreeA(nodo->s,parola);
break;
case (-1):
nodo->d = AggNodo_TreeA(nodo->d,parola);
break;
default:
//Se le parole sono uguali incremento il valore della frequenza
nodo->Elemento.freq = nodo->Elemento.freq + 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.parola);
printf(" FREQUENZA: %d ", nodo->Elemento.freq);
//Richiamo della funzione sul ramo destro
Print(nodo->d);
}
}
struct Albero * AggNodo_TreeF(struct Albero *sorg, struct Albero *dest)
{
if (dest == NULL)
{
//Creazione nuovo nodo dell'albero
dest = (struct Albero*) malloc(sizeof(struct Albero));
//Imposto il valore dei puntatori ai nodi figli
dest->d = NULL;
dest->s = NULL;
//Impostazione della frequenza
dest->Elemento.freq = sorg->Elemento.freq;
//Allocazione della memoria per la stringa contenete la parola
dest->Elemento.parola = malloc(sizeof(sorg->Elemento.parola));
//Copia della stringa
strcpy(dest->Elemento.parola,sorg->Elemento.parola);
}
else
{
//Comparazione Frequenza
if ( dest->Elemento.freq < sorg->Elemento.freq)
{
dest->s = AggNodo_TreeF(sorg,dest->s);
}
else
{
dest->d = AggNodo_TreeF(sorg,dest->d);
}
}
return dest;
}
/*Funzione che crea l'abero delle frequenze partendo dall'abero ordinato
per
alfabeto passato in input*/
void CreaAlberoF(struct Albero *sorg)
{
struct Albero *nodoprec;
if (sorg != NULL)
{
CreaAlberoF(sorg->s);
if (treeF == NULL)
{
treeF = AggNodo_TreeF(sorg, treeF);
}
else
{
AggNodo_TreeF(sorg, treeF);
}
CreaAlberoF(sorg->d);
}
} | | | | 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(struct Albero *sorg);
> //Aggiunge un nuovo nodo all'albero ordinato pre frequenze copiando i
> valori dal
> //nodo passato come sorgente
> struct Albero * AggNodo_TreeF(struct 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("\nInserire 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(treeA);
> 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 inizializzazione 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 inizializzazione 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(parola);
>
> //Assgnamento del valore alla variabile carattere
> carattere[0]=c;
> carattere[1]='\0';
> //printf("\nLunghezza 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(*carattere);
> //Concatenzazione dei caratteri per formare la parola
> parola = strcat(parola,carattere);
> //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(treeA,parola);
> }
> else
> {
> AggNodo_TreeA(treeA,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]
> }
> //Reinizializzazione 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(struct 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.freq = 1;
>
> //Allocazione della memoria per la stringa contenete la parola
> *nodo->Elemento.parola = malloc(sizeof(parola));[/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.parola == 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. |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,449 network members.
|