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);
}
} 6 2001
TC wrote: 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); } }
Please translate your comments in English would you?
TC schrieb: //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);
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?
AK schrieb: Please translate your comments in English would you?
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.
TC wrote: 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>
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
#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
// 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.
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
See what I mean about // style comments being a pain on Usenet?
//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;
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.
//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));
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.
NF[0]='\0';
do { scanf("%s",NF); //Lettura del nome del file
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.
} while (strlen(NF)<4);
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.
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);
That is a bad habit. In general any non-zero value is treated as true in C.
} while (!fOK);
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");
You might as well use puts, although there is nothing technically wrong
with printf here.
do { scanf("%d", &iScelta);
Check the return value of scanf. Also, read up on what will happen if
the user enters something other than a number.
}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
What is the point of a comment that just restates the name of a variable?
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));
See previous comments about malloc usage. Also, sizeof(char) is 1 by
definition. This applies even if a char is 324857324985739 3485 bits long.
carattere[0]='\0';
//Istanziazione e inizializzazion e della variabile parola //parola = (char*)malloc(1 *sizeof(char)); // parola[0]='\0';
Why is the above commented out? It is the only initialisation for this
variable. Also see previous comments about malloc.
while(!feof(pf) ) //Ripete fino alla fine del file {
fread(&c,1*size of(char),1,pf); //Lettura del carattere
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.
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);
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.
//Assgnamento del valore alla variabile carattere carattere[0]=c; carattere[1]='\0'; parola=(char*)r ealloc(parola,( lung+1)*sizeof( char));
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.
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);
}
}
TC wrote: I have make some corrections, but the program doesn't correctly work. Help me please.
Help us. In future tell us what you mean by "not working".
/*Inclusione librerie*/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <malloc.h>
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.
/*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
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.
//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
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.
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');
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.
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));
Better, but multiplying by sizeof(char) is pointless as it is defined as
being 1. Also, what if malloc fails?
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
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.
{ c = fgetc(pf);//Lettura del carattere
You need to check for feof here instead. You also need to check for it
failing for other reasons.
//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)))) {
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.
printf("\n REALLOC : Errore di allocazione della memoria.\n"); getch();
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?
} //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);
Don't you need the pointer you have just thrown away? This is probably
the cause of the problem you had spotted.
} //Reinizializzazi one della variabile parola parola= realloc(parola, sizeof(char));
See previous comment about realloc.
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));
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.
if(nodo->Elemento.parol a == NULL) { printf("\n Errore di allocazione della memoria.\n"); }
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: PHPkemon |
last post by:
Hi there,
A few weeks ago I made a post and got an answer which seemed very logical.
Here's part of the post:
PHPkemon wrote:
> I think I've figured out how to do the main things like storing products
in
|
by: d.warnermurray |
last post by:
I am doing a project for school that involves creating help files for a html
authoring tool.
If you could help me with answers to some questions it would really help.
1. What tasks do you expect an html authoring tool to help you accomplish?
2. What do you expect from online help for a html authoring tool?
3. What audience do you think a freeware html authoring tool is directed
towards?
|
by: Mark Reed |
last post by:
Hi all,
I am trying to learn a little about programming (I know next to nothing
so far) and have found some code which hides the toolbars. However, this bit
of code is a little too effective and hides all of them including hiding the
database window, disabling menu changes. What I am after is the same effect
as disabling all the check boxes in startup which still leaves 'File',
'Edit', 'Insert','Records','Window' &'Help'. I want to do this...
|
by: dixie |
last post by:
Help, I'm really out of my depth here (not unusual I hear you say :-). I
have just installed HTML Help in an application. I told it in the Project
Properties the path to the help file. I then type in a command line that
runs the help in the correct Context from a button on each form. It all
worked fine - HERE.
The problem is that when I sent it out to a site, the help file was not able
to be accessed because it was my path in the...
|
by: Timothy Shih |
last post by:
Hi, I am trying to figure out how to use unmanaged code using P/Invoke. I
wrote a simple function which takes in 2 buffers (one a byte buffer, one a
char buffer) and copies the contents of the byte buffer into the character
pointer. The code looks like the following:
#include <stdio.h>
#include <stdlib.h>
#include "stdafx.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
| |
by: Jason |
last post by:
Hi,
I was wondering if any could point me to an example or give me ideas on how
to dynamically create a form based on a database table? So, I would have a
table designed to tell my application to create certain textboxes, labels,
and combo boxes? Any ideas would be appreciated.
Thanks
|
by: Allen |
last post by:
I have a class that returns an arraylist. How do I fill a list box from what
is returned? It returns customers which is a arraylist but I cant seem to
get the stuff to fill a list box. I just learning and really need some help
bad.
Public Shared Function GetAll() As ArrayList
Dim dsCustomer As New DataSet()
Dim sqlQuery As String = "SELECT Name, Address, PhoneNo " & _
"FROM CustomerTable"
Try
|
by: inkexit |
last post by:
I need help figuring out what is wrong with my code. I posted here a
few weeks ago with some code about creating self similar melodies in
music. The coding style I'm being taught is apparently a lot different
from what the pros around here use. I really need help with debugging
some program errors more than anything, even though my coding style
might not be perfect.
Anyway here is my code. About the only things that work right are...
|
by: glenn123 |
last post by:
Hi, i am just about out of time to produce a working jukebox which has to perform these functions: to play music files when a track is chosen from a list which when the user presses the change genre button the list is populated with a list of that genre.
I have got the interface done to satisfaction, my problem is that when i press the change genre button nothing happens and when i select a track to play from the list which is setvisible and...
|
by: JonathanOrlev |
last post by:
Hello everybody,
I wrote this comment in another message of mine, but decided to post it
again as a standalone message.
I think that Microsoft's Office 2003 help system is horrible, probably
the worst I
ever seen.
I almost cannot find anything I need, including things I
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
| |
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |