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)