|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
[C] ho bisogno di un consiglio
salve a tutti, dovrei, dato un file di testo con tot parole (prese da un articolo di giornale, o da un libro, non importa), fare in modo da prendere tutte le parole, e poi ordinarle in ordine alfabetico..tutto questo in C.
Mi sono bloccato sulla funzione per dividete tutto il testo in parole, per poi prendere le singole parole ed ordinarle in ordine alfabetico, oppure in ordine di ehm...come si dice quando una parola compare più volte..vabbè avete capito ![]() io pensavo di metterli in un array, ma ce ne vorrebbe uno per ogni parola...oppure pensavo alle liste, ma non sò bene come implementare il tutto. Potreste darmi una mano??? Non voglio il codice scritto in C, perchè voglio farlo da solo, ma vorrei un piccolo aiuto su come poter procedere! grazie Ultima modifica di welfi : 06-10-2007 alle 16:26. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Per la lettura delle parole potresti usare fscanf, ad esempio. Per memorizzarle potresti usare un array espandibile (lo riallochi dinamicamente). Per l'ordinamento ... dipende, potresti implementare il classico bubble sort o usare la qsort().
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#3 | |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
Quote:
a[0]"casa" a[1] = "mare".. ecc...non avevo capito nulla sugli array di stringhe allora ![]() e nel caso volessi implementarlo con lista? Ultima modifica di welfi : 06-10-2007 alle 16:47. |
|
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Se intendi usare un array di stringhe (e non altre strutture dati come le liste), dovresti fare "un array di puntatori a char", in cui ogni puntatore punta ad una stringa, il cui spazio di memoria va allocato appositamente. Bisogna vedere poi se vuoi realizzare un array di una dimensione massima prefissata (più semplice) o un array "espandibile" da (ri)allocare a runtime (meno facile). Se fisso, si può fare: char *stringhe[500]; /* 500 stringhe */ Se riallocabile: char **stringhe; ma va (ri)allocato a runtime. stringhe = (char**) malloc (500 * sizeof (char*)); se non basta, a runtime si fa: stringhe = (char**) realloc (stringhe, 1000 * sizeof (char*)); Tutto questo è solo per allocare lo spazio per i puntatori, non per i caratteri delle stringhe. Per ogni stringa che leggi, allocherai memoria sufficiente, ci copierai la stringa e assegnerai il puntatore ad un elemento dell'array.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) Ultima modifica di andbin : 06-10-2007 alle 16:51. |
|
![]() |
![]() |
![]() |
#5 |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
allora mi metto a ripetere un po gli array di puntatori....ma per le liste anche dovrei usare gli array? tipo ogni elemento della lista dovrebbe avere una parola. ora questa parola o viene memorizzata in un array di int (come pensavo di fare) oppure in un array di puntatori..sbaglio?
|
![]() |
![]() |
![]() |
#6 |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
nel frattempo ti posto quello che ho fatto fin'ora, con gli array di int, che sembra più semplice (poi lo implementerò anche con gli altri casi);
Nella funzione, dove c'è l'if, mi manca un metodo per inserire caratteri di vlta in volta, esempio se c non è uno spazio, mette il carattere in a, se il succ. carattere non è uno spazio, vuol dire che la parola non è finita e lo deve aggiungere ancora ad a con lo stesso indice del carattere precedente, finchè nn trova lo spazio e la parola risulta finita. Codice:
void dividi_in_parole(FILE *fp, int a[] ){ int *stringa; int c, i = 0; do{ c = getc(fp); if (c != 32) { ; } else {i++;} }while (c != EOF); } int main(int argc, char *argv[]) { FILE *fp; int array_parole[500] ={'0'}; fp = fopen("/home/peppe/Desktop/file.txt", "r"); dividi_in_parole(fp, array_parole); fclose(fp); return EXIT_SUCCESS; } |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Qui hai diverse soluzioni: o usi un array di puntatori a char o usi una qualche altra struttura dati come una lista linkata. Per la lista linkata dovresti fare una piccola struttura (struct) che contiene il tuo dato (e qui puoi/devi decidere come gestire lo spazio per i caratteri) e un puntatore all'elemento successivo. Però nota che se devi poi ordinare il tutto, una lista linkata è meno semplice da ordinare rispetto ad un array. Un esempio basilare di gestione di una lista linkata l'ho fatto di recente in <questa> discussione.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
No no no. Lascia perdere gli int perché sei sulla strada completamente sbagliata.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) Ultima modifica di andbin : 06-10-2007 alle 17:26. |
![]() |
![]() |
![]() |
#9 |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
ti ringrazio molto per i consigli!!! inizio a studiarmi gli array di puntatori e inizio a implementare qualcosa...poi passo allo studio delle liste link
nel caso posto di nuovo ![]() |
![]() |
![]() |
![]() |
#10 |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
ehm, posso fare un altra domandina??? io ho questo file di testo, ma come faccio a caricare, ad esempio in una variabile "stringa", una parola letta dal file e non un singolo carattere?(per poi metterla nell'array di puntatori)???
oppure sapendo come caricare un singolo carattere alla volta(usando getc) come li metto tutti insieme finchè non trovo lo spazio (carattere 32)?? Ultima modifica di welfi : 06-10-2007 alle 17:43. |
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Certo, il forum è fatto per questo.
Quote:
Codice:
#include <stdio.h> int main (void) { FILE *f; char buf[101]; if ((f = fopen ("un_file_di_testo.txt", "r")) != NULL) { while (fscanf (f, "%100s", buf) == 1) printf ("[%s]\n", buf); fclose (f); } return 0; } Nota che 'buf' è uno solo e contiene di volta in volta l'ultima parola letta. Per tale motivo non si dovrebbe mettere nell'array l'indirizzo di buf. Per ogni parola, devi determinarne la lunghezza, allocare dinamicamente della memoria (e nota bene, va allocato 1 carattere in più per il nullo finale), poi copiare in questa area la stringa e a quel punto puoi assegnare nell'array l'indirizzo di questa area.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#12 |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
conosco fscanf, ma credevo che leggesse dal file, come hai scritto tu, 100 CARATTERI, invece legge un massimo di 100 caratteri, ma restituisce ogni volta una stringa delimitata dallo spazio!!!! cavolo, non l'ho trovata scritta da nessuna parte questa ottima utilità di fscanf!!!
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
La documentazione del VC++ dice: scanf Width Specification width is a positive decimal integer controlling the maximum number of characters to be read from stdin. No more than width characters are converted and stored at the corresponding argument. Fewer than width characters may be read if a white-space character (space, tab, or newline) or a character that cannot be converted according to the given format occurs before width is reached.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#14 |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
nel mio in italiano non c'è..lo devo cambiare! visto che siamo in tema, mi puoi consigliare un buon libro (se proprio non c'è in italiano va bene anche inglese) di C fatto bene però
![]() cmq credo di essere arrivato a buon punto, ho fatto in modo di dividere le parole da un testo qualunque, togliendo eventuali punteggiature dopo la parola (virgole, punti) ed ogni parola va nell'array di puntatori. tutto funziona bene, ma dopo 6 parole esce con un errore. no sò perchè, ma anche cambiando le parole dopo 6 parole lette da errore.!!!! ti posto il codice, se potreseti dargli un'occhiata quando vuoi cosi mi aiuti a capire cosa c'è che nn va...grazie Codice:
//elimina tutta la punteggiatura! e restituisce la lunghezza della parola int elimina_schifezze(char temp[]) { int i =0; while(temp[i]>48) i++; temp[i] = '\0'; return i; } //divide in parole il testo void dividi_in_parole(FILE *fp, char *a[] ){ char temp[30]; int lunghezza, indice; indice = -1; while (fscanf (fp, "%30s", temp) == 1){ indice++; //conta le parole lunghezza = elimina_schifezze(temp); //lunghezza effettiva della parola a[indice] = calloc(lunghezza+1,sizeof(char)); strcpy(a[indice], temp); printf("%s\n", a[indice]);//controllo che parole ha inserito e come le ha inserite } } int main(int argc, char *argv[]) { FILE *fp; char *array_parole[500]; int lunghezza; //apro il file fp = fopen("/home/peppe/Desktop/file2.txt", "r"); //divido in parole il testo dividi_in_parole(fp, *array_parole); //chiudo il file fclose(fp); return EXIT_SUCCESS; } Ultima modifica di welfi : 07-10-2007 alle 11:03. |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
L'asterisco * non ci vuole, perché passi un tipo di dato incompatibile (e il compilatore dovrebbe pure segnalartelo).
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#16 |
Junior Member
Iscritto dal: Oct 2007
Messaggi: 9
|
ora va bene, ti ringrazio!
ps, per caso puoi consigliarmi un buon libro e completo di C, fatto bene, in italiano oppure(se proprio in italiano nn c'è) in inglese?? |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Jun 2005
Città: Napoli
Messaggi: 2599
|
ma se si volesse realizzare il comportamento di fscanf con un altra funzione, come si dovrebbe fare?? cioè se nel codice seguente:
Codice:
if ((f = fopen ("un_file_di_testo.txt", "r")) != NULL) { while (fscanf (f, "%100s", buf) == 1) printf ("[%s]\n", buf); fclose (f); }
__________________
Hp pavilion dv6-1250el [cpu: P8700 - ati radeon hd 4650 1 gb - 4 gb ram - hd 320 7200 rpm!] Garmin Official Thread |
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Sep 2005
Città: 127.0.0.1
Messaggi: 3321
|
Deitel & Deitel, C: Corso Completo di Programmazione, edito da Apogeo.
__________________
Intel Core 2 Duo E6420 | 2x1 GB Team Group XTreem PC6400 CL4 + 2x2 GB Corsair XMS2 | Gigabyte P35C - DS3R | XFX nVidia GeForce 8800 GTS 640 MB Extreme Edition | Western Digital Raptor 74GB | Samsung HD153WI 1,5 TB | NEC ND-4551A | Seasonic S12 600W | Coolermaster Stacker STC-01 Black | Acer AL1916w. ~ Trattative positive: 30 negative: 1 (Insane_Tech) |
![]() |
![]() |
![]() |
#19 | |
Senior Member
Iscritto dal: Jun 2005
Città: Napoli
Messaggi: 2599
|
Quote:
__________________
Hp pavilion dv6-1250el [cpu: P8700 - ati radeon hd 4650 1 gb - 4 gb ram - hd 320 7200 rpm!] Garmin Official Thread |
|
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Un'altra soluzione potrebbe essere quella di leggere "a righe" con fgets() e poi spezzare la riga in parole tramite strtok() (specificando come delimitatori lo spazio, magari anche il tab o altro che vuoi).
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 06:18.