[C++] Creazione di un dizionario
Vorrei creare un codice che mi permetta di leggere da un testo,di salvare le parole in una lista e di ristamparle.Di seguito quello che ho scritto :
Il file che apro,infinito,contiene la frase :"ciao io mi chiamo Antonio".Da ciò potete capire i valori nel for principale .
1)C'è un modo per poter determinare a priori il numero di operazioni minime necessarie per eseguire correttamente il programma senza che esso faccia operazioni inutili (in più) ???
Ovviamente oltre a chiedere all'utente quanti caratteri ci sono nel testo!!
2)Non riesco a stampare l'ultima parola perchè nel ciclo for principale ,quando i=25 , non viene eseguita questa riga di codice
che mi permette di eseguire l'ultimo for nel quale stampo l'ultima parola.Ho utilizzato dei printf e ho verificato che la condizione i=25 è assunta nell'ultimo ciclo quindi dovrei riuscire a salvare nel vettore lunghezza_parola la lunghezza della parola necessaria per stamparla ma non è così! Dov'è che sbaglio??
#include <cstdlib> #include <iostream> using namespace std; struct dizionario{ char parola[20]; struct dizionario *next; }*attuale,*leggi,*cima; int main(int argc, char *argv[]) { int i,j=0,k=0; int lunghezza_parola[5]; char c; FILE *pf; pf=fopen("c:/users/valerio/desktop/infinito.txt" ,"r"); for(i=0;i<26;i++) { fscanf(pf ,"%c" ,&c); if(i==0) { attuale=(dizionario *)malloc(sizeof(dizionario)); attuale->parola[j]=c; cima=attuale; attuale->next=NULL; j++; } else if((c==' ')&&(i!=25)) { attuale->next=(dizionario *)malloc(sizeof(dizionario)); attuale=attuale->next; attuale->next=NULL; lunghezza_parola[k]=j; k++; j=0; } else if((i!=0)&&(c!=' ')) { attuale->parola[j]=c; j++; } else if(i==25) { lunghezza_parola[k]=j; } } j=0; for(leggi=cima;leggi->next!=NULL;leggi=leggi->next) { for(i=0;i<lunghezza_parola[j];i++) { printf("%c" ,leggi->parola[i]); } printf("\t"); j++; } for(i=0;i<lunghezza_parola[j];i++) { printf("%c" ,leggi->parola[i]); } printf("\n"); system("PAUSE"); return EXIT_SUCCESS; }
Il file che apro,infinito,contiene la frase :"ciao io mi chiamo Antonio".Da ciò potete capire i valori nel for principale .
1)C'è un modo per poter determinare a priori il numero di operazioni minime necessarie per eseguire correttamente il programma senza che esso faccia operazioni inutili (in più) ???
Ovviamente oltre a chiedere all'utente quanti caratteri ci sono nel testo!!
2)Non riesco a stampare l'ultima parola perchè nel ciclo for principale ,quando i=25 , non viene eseguita questa riga di codice
else if(i==25) { lunghezza_parola[k]=j; }
che mi permette di eseguire l'ultimo for nel quale stampo l'ultima parola.Ho utilizzato dei printf e ho verificato che la condizione i=25 è assunta nell'ultimo ciclo quindi dovrei riuscire a salvare nel vettore lunghezza_parola la lunghezza della parola necessaria per stamparla ma non è così! Dov'è che sbaglio??
Risposte
La soluzione più semplice al problema proposto fa uso delle librerie standard nel seguente modo:
1. Lettura dell'intero file in una stringa
2. Uso di strtok per trovare tutti gli spazi nella stringa e usare tale informazione per estrarre le parole.
3. Ciclo di stampa della lista.
Il metodo classico per risolvere il primo punto è il seguente (non ho provato il codice):
Questa funzione dovrebbe rispondere alla tua domanda su come ottenere la lunghezza del file. Ovviamente il discorso sarebbe diverso se volessi limitarti solo alla lettura di una riga per volta. In questo caso conviene usare fgets (o qualcosa di simile).
Per quanto riguarda strtok non credo tu possa usarlo (elimina un po' il senso dell'esercizio..). Ma immagino possa essere utile conoscere la sua esistenza.
Per quanto riguarda infine il tuo errore.. L'ultima lettera della tua stringa è 'o' per cui rispetta le condizioni (i!=0)&&(c!=' ') e quindi il codice entra nel ramo precedente a quello dove vorresti entrasse.. In effetti il codice andrebbe probabilmente riscritto un po' diversamente.
1. Lettura dell'intero file in una stringa
2. Uso di strtok per trovare tutti gli spazi nella stringa e usare tale informazione per estrarre le parole.
3. Ciclo di stampa della lista.
Il metodo classico per risolvere il primo punto è il seguente (non ho provato il codice):
char *read_entire_file(const char *filename, int *size) { FILE *file = fopen(filename, "rb"); if (!file) { return NULL; } fseek(file, 0, SEEK_END); /* vai alla fine del file */ size_t len = ftell(file); /* ottieni dimensione del file.. */ rewind(file); /* torna all'inizio */ char *content = (char *)malloc(len+1); if (!content) { return NULL; } size_t ret = fread(content, 1, len, file); if (ret != len) { free(content); return NULL; } /* errore durante la lettura.. */ content[len] = '\0'; if (size) { *size = len; } /* restituisce la lunghezza del file */ return content; }
Questa funzione dovrebbe rispondere alla tua domanda su come ottenere la lunghezza del file. Ovviamente il discorso sarebbe diverso se volessi limitarti solo alla lettura di una riga per volta. In questo caso conviene usare fgets (o qualcosa di simile).
Per quanto riguarda strtok non credo tu possa usarlo (elimina un po' il senso dell'esercizio..). Ma immagino possa essere utile conoscere la sua esistenza.
Per quanto riguarda infine il tuo errore.. L'ultima lettera della tua stringa è 'o' per cui rispetta le condizioni (i!=0)&&(c!=' ') e quindi il codice entra nel ramo precedente a quello dove vorresti entrasse.. In effetti il codice andrebbe probabilmente riscritto un po' diversamente.