ciao a tutti!
Ho estremamente bisogno dell'aiuto di qualcuno!!
Devo implementare un programma in C con le seguenti modalità:
Il programma legge coppie di dati nome - email dal file passato come parametro e salvi i dati in una tabella hash(vettore).
Esempio file con nomi e ind. mail:
Mario - rossi.mario@tiscali.it
Nicola - bianchi.nicola@hotmail.it
Lucia - verdi.lucia@hotmail.it
Andrea - blu.andrea@libero.it
Antonio - neri.antonio@tiscali.it
Rossana - violetti.rossana@gmail.it
Stefano - galli.stefano@hotmail.it
Elena - rosetti.elena@tiscali.it
Erica - giacomini.erica@hotmail.it
Il programma permette all'utente di specificare un nome sullo standard input e dopo aver premuto il tasto invio , il programma cerca il corrispondente indirizzo mail e lo stampa su standard output. Il prog ripete il comportamento descritto finchè l'utente non preme Ctrl-D.
E' richiesta una tabella hash che segua la seguente strategia di scansione lineare:
- per inserire una tupla con chiave e valori viene utilizzata la funzione di hash sulla chiave(nome) per determinare l'indice: se l'indice corrisponde ad una riga libera, la tupla viene salvata, altrimenti viene salvata nella riga libera successiva;
- per cercare una tupla si usa la funz hash sulla chiave e poi si controlla se la chiave data corrisponde alla chiave della riga con l'indice trovato: se è così si restituiscono i valori, altrimenti si passa a controllare le righe successive.
La funzione hash utilizzata è:
funzHash(key) = ((ASCII(car1)+ASCII(car2))mod(DIM_TAB)
(vedi implementazione in C nel codice)
Il codice del mio programma è questo:
codice:#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 1024 // lunghezza massima di un array #define TABLE_SIZE 50 // dimensione della tabella hash #define LENGHT 60 // lunghezza max delle stringhe struct Hash { // definizione della struttura Hash char *key; char *email; }; // prototipi delle funzioni void search(char *key); unsigned funzHash(char *key); unsigned linearProbing(unsigned entry); int fileIsEmpty(FILE *fp); typedef struct Hash TAB; // creo una struttura di tipo Hash e la chiamo TAB typedef TAB *TABPTR; // creo un puntatore alla struttura appena creata char *table[TABLE_SIZE]; // main main(){ int c, i, key; char s[MAX], temp[MAX]; char file_name[MAX] ; // nome del file char s1[MAX], user_name[MAX], temp1[MAX];// vettori per contenere il nome utente letto da file char s2[MAX], data[MAX], temp2[MAX]; // vettori per contenere i dati dell' utente letti da file FILE *fp; // puntatore a file printf("Inserire il nome del file (con estensione):\n"); // lettura del nome del file da stdin scanf("%s", file_name); fp = fopen(file_name, "r"); // chiamata a fopen if (fp == NULL){ // controllo esistenza file specificato printf("Il file '%s' non esiste\n", file_name); // se non esiste --> errore } else if (! fileIsEmpty(fp)) { // controllo se il file è vuoto printf("Attenzione! Il file '%s' è vuoto\n", file_name); // se è vuoto --> errore } else { // ciclo per inserire i dati in una cella libera della tabella hash while((fgets(s1, MAX, fp)) != NULL) { // lettura delle righe del file i = 0; while (s1[i] != ' ') { // copia della parola letta user_name[i] = s1[i]; i++; } user_name[i] = '\0'; // carattere di terminazione stringa strcpy(temp1,user_name); // salvataggio della parola letta in un array temporaneo linearProbing(funzHash(temp)); // uso della funzione hash per individuare cella libera dove salvare i dati // ciclo per inserire il nome e l'email dell' utente while((fgets(s2, MAX, fp)) != NULL) { // lettura delle righe del file i = 0; while ((s2[i] != '\n') && (i < strlen(s2))) { // copia della riga letta ed eliminazione di '\n' data[i] = s2[i]; i++; } data[i] = '\0'; // carattere di terminazione stringa strcpy(temp2,data); // salvataggio della linea letta in un array temporaneo } } } fclose(fp); // chiusura del file printf("\nInserire il nome dell'utente e premete Invio (Ctrl+D per terminare):\n"); //lettura del nome dell'utente da stdin while((c = getchar()) != EOF) { // lettura di un carattere da stdin s[i] = c; // inserimento del carattere nell'array della stringa corrente while ((c = getchar()) != ' ') { s[++i] = c; // inserimento dei successivi caratteri validi nell'array } s[++i] = '\0'; // carattere di terminazione stringa } search(s); // chiamata alla funzione di ricerca return 0; // uscita con successo } // funzione che cerca l'indirizzo email dell'utente letto da stdin void search(char *key){ // key = s int i, value1, value2; // nel vettore->s ho il nome dell' utente value1 = funzHash(key); // uso della funzione hash per la ricerca value2 = linearProbing(funzHash(key)); // uso della funzione hash per la ricerca senza collisione for (i = 0; i < TABLE_SIZE; i++) { // scorre il vettore if ((i == value1) && (key == table[i])) { // controlla se il risultato della funzHash corrisponde all'indice della tabella e se la chiave passata come parametro corrisponde alla chiave della riga con l'indice trovato printf("%s\n",key); // ritorna i dati dell'utente trovato } else if ((i == value2) && (key == table[i])) { // controlla nelle posizioni successive printf("%s\n",key); } else { printf("Errore! Valore non trovato!\n"); // non ci sono corrispondenze } } } // funzione di hash unsigned funzHash(char *key) { unsigned entry; entry = ((int)key[1] + (int)key[2]) % TABLE_SIZE; if (entry < 0) { entry += TABLE_SIZE; } return entry; } // gestione delle collisioni con il metodo di linear probing: qnd si incontra una // collisione si utilizza l'indice successivo fino a che non si trova una casella libera unsigned linearProbing(unsigned entry) { int count = TABLE_SIZE; while (table[entry] != NULL || count--> -1) { entry = (entry + 1) % TABLE_SIZE; } if (count == 0) { printf("Errore! La tabella è piena! \n"); return -1; } return entry; } // funzione che controlla se un file è vuoto (ritorna 0 se il file è vuoto, un intero > 0 altrimenti) int fileIsEmpty(FILE *fp){ int count = 0; // inizializzazione contatore caratteri char c; while ((c = fgetc(fp)) != EOF){ // lettura dei caratteri fino all'EOF if ((c != '\t') && (c != ' ') && (c != '\n')) // è stato trovato un "whitespace" character count++; // --> incremento del contatore } rewind(fp); // riazzeramento del puntatore a file return count; // viene restituito il valore del contatore }
Riesco a compilarlo (gcc -o rubrica_mail rubrica_mail.c)
ed eseguirlo (./rubrica_mail)
Inserisco il nome del file (rubrica.txt) e il nome di uno degli utenti del file, però il programma non esegue niente; secondo me c'è qualche errore nel codice di search(char *key), probabilmente nell' IF.
Oppure qualche piccolo errore nel main (ma nn credo)
QUALCUNO RIESCE AD AIUTARMI??
Grazie mille in anticipo!
(vi allego anche il codice in C se vi potesse servire)

Rispondi quotando