Ordinamento Lista[C]
Ragazzi potreste aiutarmi a capire dove sbaglio? Vi spiego esercizio e problema. In pratica devo ordinare in modo alfabetico le parole che si trovano all'interno di un file di testo. Avevo già risolto l'esercizio in un modo, ma al professore non è piaciuto e quindi mi ha detto di migliorarlo. Ho pensato allora di usare le liste. Il mio programma, quindi, deve prendere una per una le parole del file ed inserirle nella lista in modo ordinato. Il programmino viene compilato, ma all'avvio va in segmetation fault! Di sicuro so che il problema sta nella funzione insert, ma dove? Grazie in anticipo dell'eventuale aiuto!
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Lista{ char *stringa; struct Lista *next; }; typedef struct Lista LISTA; typedef LISTA* NODO; void ordina(FILE*); void insert(NODO*,char*); void printList(NODO); int main(){ FILE *input; if ((input = fopen("input.txt","r")) == NULL) { printf("errore: file supporto.txt non trovato!"); exit(-1); } ordina(input); return 0; } void insert(NODO* node, char* str){ NODO nuovo,curr,previus; printf("La parola selezionata e': %s",str); nuovo->stringa =(char*) malloc((strlen(str)+1)*sizeof(char)); if(nuovo->stringa != NULL){ strcpy(nuovo->stringa,str); nuovo->next = NULL; previus = NULL; curr = *node; while(curr !=NULL && strcmp(str,curr->stringa)>0){ previus = curr; curr = curr->next; } if(previus == NULL){ nuovo->next = *node; *node = nuovo; } else{ previus->next = nuovo; nuovo->next = curr; } } else printf("Non c'è memoria disponibile\n"); } void ordina(FILE* input_file){ NODO startPtr = NULL; int j; //Vettore di supporto char parola[21]={0}; //Estraggo le parole e le metto in una lista int chr,controllo=0,i=0; while(!feof(input_file)){ chr = fgetc(input_file); if ((chr > 64 && chr < 91) || (chr > 96 && chr < 123)){ parola[i]=chr; controllo = 1; i++; }else{ if(controllo == 1){ insert(&startPtr,parola); for(j=0;j<21;j++) parola[j]=0; } i=0; controllo = 0; } } printList(startPtr); } void printList(NODO currentPtr) { if(currentPtr == NULL) printf("\nla lista e' vuota\n"); else{ printf("\nla lista e':\n"); while(currentPtr != NULL){ printf("%s --> ", currentPtr->stringa); currentPtr = currentPtr->next; } printf("NULL\n\n"); } }
Risposte
Avevo già risolto l'esercizio in un modo, ma al professore non è piaciuto e quindi mi ha detto di migliorarlo. Ho pensato allora di usare le liste.
Tanto per curiosità.. di che metodo si trattava? E quali erano le critiche?
Non posso testare in questo momento il codice, potresti però postare il file di testo che stai usando per fare i test? Il problema si verifica anche in casi semplici come file composti da una singola parola molto corta o addirittura un file vuoto? Si verifica anche se ignori l'inserimento nella lista? Hai provato ad inserire le parole tu nella lista senza leggerle da file? Il problema si verifica anche in questo caso? C'è una ragione per cui stai usando un test come:
(chr > 64 && chr < 91) || (chr > 96 && chr < 123)
al posto di usare le corrette funzioni nella libreria ctype? Perché usi il codice ASCII dei caratteri (supponendo che sia quello che stai facendo..) invece di scrivere il corrispondente carattere tra apici? Il tuo test diventerebbe un non esattamente leggibile:
(chr > '@' && chr < '[') || (chr > '`' && chr < '{')
ma in realtà si voleva scrivere semplicemente
(chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z')
e il compilatore probabilmente genererebbe un codice del tutto uguale avendo scritto qualcosa di molto più chiaro e leggibile. In alternativa, includendo ctype.h si potrebbe scrivere semplicemente
isalpha(chr)
Quando ho tempo di testare meglio il codice potrò dire qualcosa di più..
Innanzi tutto la funzione che avevo fatto era la seguente e funziona correttamente!!!! Il professore però ha detto la seguente frase: "Lei è andato a messina, passando da Trapani e Catania, il codice è troppo complesso e molto pesante per quanto riguarda l'efficienza!".
In un file .txt ho scritto la seguente stringa:
Pippo Pappa Peppa
In pratica, testando più volte il programma, attraverso il debugging, mi sono accorto che c'è qualche problema nell'allocazione della memoria, poichè non appena il programma(in fase di esecuzione) arriva li, tutto va in crash!!
Per favore dammi una mano perchè non riesco a capire dove sta l'errore. Comunque ora apporto le correzioni che mi hai consigliato!
void ordine_alfabetico(FILE** argomenti, int dim){ int i = 0, j = 0, parole_dim; int a = 0, b = 0; char** vett; char chr; char* supporto; FILE* file_ordinato; FILE* supporto_file; if ((supporto_file = fopen("supporto.txt","w")) == NULL) { printf("errore: file supporto.txt non trovato!"); exit(-1); } supporto = (char*)malloc(sizeof(char)*256); if ((file_ordinato = fopen("ordine_alfabetico.txt","w")) == NULL) { printf("Ferrore: file ordine_alfabetico.txt non trovato!"); exit(-1); } for(i = 0; i < dim; i++){ int chr,controllo = 0; while (!feof(argomenti[i])){ chr = fgetc(argomenti[i]); if ((chr > 64 && chr < 91) || (chr > 96 && chr < 123)){ fprintf(supporto_file, "%c", chr); controllo = 1; }else{ if (controllo == 1) fprintf(supporto_file, "\n"); controllo = 0; } } } fprintf(supporto_file, "\n"); fclose(supporto_file); if ((supporto_file = fopen("supporto.txt","r")) == NULL) { printf("errore: file supporto.txt non trovato!"); exit(-1); } parole_dim = parole(supporto_file); vett = (char**)malloc(sizeof(char*)*parole_dim + 1); for(i = 0; i < parole_dim + 1; i++) vett[i]=(char*)malloc(sizeof(char)*64); fclose(supporto_file); if ((supporto_file = fopen("supporto.txt","r")) == NULL) { printf("errore: file supporto.txt non trovato!"); exit(-1); } for(i = 0; i < parole_dim; i++){ chr = fgetc(supporto_file); while (chr != '\n'){ vett[a][b] = chr; b++; chr = fgetc(supporto_file); if (b == 60) break; } b = 0; a++; } for(i = 0; i < parole_dim-1;i++){ for(j = parole_dim-1; j > i; j--){ if (strcmp(vett[j-1],vett[j]) > 0){ supporto = vett[j-1]; vett[j-1] = vett[j]; vett[j] = supporto; } } } for(i = 0; i < parole_dim; i++) fprintf(file_ordinato, "%s\n", vett[i]); }
In un file .txt ho scritto la seguente stringa:
Pippo Pappa Peppa
In pratica, testando più volte il programma, attraverso il debugging, mi sono accorto che c'è qualche problema nell'allocazione della memoria, poichè non appena il programma(in fase di esecuzione) arriva li, tutto va in crash!!
Per favore dammi una mano perchè non riesco a capire dove sta l'errore. Comunque ora apporto le correzioni che mi hai consigliato!
Ok ok.... ho risolto avevo dimenticato un'allocazione di memorira =)