Ciao ragazzi. In poche parole l'esercizio che devo svolgere consiste nell'inserire dei dati presi da file in una struttura dati (io ho scelto di usare una lista), inserire un nuovo elemento da tastiera, cancellare un elemento da tastiera e ordinare gli elementi secondo una delle quattro chiavi che ho scritto sotto.
Il file che uso contiene questo:
Barolo 19E2 2011 Asti
Chianti 48K1 2009 Siena
Amarone 68A5 2010 Verona
Gravner 39U4 2006 Udine
Valentini 57L3 2012 Chieti
Il formato del file sarebbe: nome_vino, id_bottiglia, anno_produzione, luogo_imbottigliamento.
Premettendo che sono ancora piuttosto scarso in programmazione, ho trovato un problema piuttosto fastidioso che non riesco a risolvere. Praticamente quando vado a inserire un nuovo elemento, anche se questo esiste già nella lista, viene inserito lo stesso e invece non dovrebbe. Quindi la prima cosa che ho pensato è che il controllo che dovrebbe impedirlo non funzioni. Tuttavia, anche con l'aiuto di un amico decisamente più esperto di me, non siamo ancora riusciti a trovare l'errore. C'è qualcuno che può aiutarmi?
Il codice che ho scritto finora è questo:
/* Inclusione librerie */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Definizione delle costanti simboliche */
#define DIM_NOME 70 /* Definizione della costante per la dimensione del nome del vino */
#define DIM_ID 20 /* Definizione della costante per la dimensione dell'id del vino */
#define DIM_ANNO 20 /* Definizione della costante per la dimensione dell'anno di produzione del vino */
#define DIM_LUOGO 70 /* Definizione della costante per la dimensione del luogo di imbottigliamento del vino */
/* Definizione della struttura dati */
typedef struct lista
{
char nome_vino[DIM_NOME+1];
char id_bott[DIM_ID+1];
char anno_prod[DIM_ANNO+1];
char luogo_imb[DIM_LUOGO+1];
struct lista *succ_p;
}lista_t;
/* Dichiarazione delle funzioni */
int inserisci_in_lista(lista_t **,
char [],
char [],
char [],
char []);
/* Definizione delle funzioni */
/* Definizione della funzione main */
int main(void)
{
/* Dichiarazione delle variabili locali */
int operazione; /* Variabile che contiene la scelta dell'utente */
int file_caricato; /* Variabile che contiene 0 se si deve ancora caricare il file, 1 se è già stato caricato */
int esegui_altre_operazioni; /* Variabile che se contiene 1 permette l'esucezione di ulteriori informazioni, altrimenti termina il programma */
int controllo; /* Variabile che controlla quando si raggiunge la fine del file */
int inserito; /* Variabile che controlla se l'inserimento è avvenuto oppure no */
int inserito1; /* Variabile che controlla se l'inserimento del nuovo vino è avvenuto oppure no */
char nome_vino[DIM_NOME+1]; /* Input: nome del vino */
char id_bott[DIM_ID+1]; /* Input: id del vino */
char anno_prod[DIM_ANNO+1]; /* Input: anno di produzione del vino */
char luogo_imb[DIM_LUOGO+1]; /* Input: luogo di imbottigliamento del vino */
FILE *file_input; /* Puntatore al file */
lista_t *testa_p; /* Dichiarazione della testa della struttura dati */
/* Inizializzo */
file_caricato = 0;
/* Inizializzo la testa della struttura = NULL */
testa_p = NULL;
/* Eseguo fino a che l'utente non decide di uscire dal programma */
do
{
/* Interfaccia del programma: contiene informazioni generali e il menù con le possibili operazioni */
printf("\n");
printf("Benvenuti nel programma.\n");
printf("Menù operazioni disponibili:\n");
printf("-Inserire i dati da file nella struttura apposita: premere '1';\n");
printf("-Inserire i dati relativi ad un nuovo vino: premere '2';\n");
printf("-Rimuovere un vino esistente e i dati ad esso correlati: premere '3';\n");
printf("-Ordinare la struttura dati in base ad una delle chiavi: premere '4';\n");
/* Acquisizione dell'operazione scelta dall'utente */
scanf("%d",
&operazione);
/* Se l'utente sceglie di inserire i dati nella struttura */
if (operazione == 1)
{
/* Il file viene caricato solamente se file_caricato = 0 */
if (file_caricato == 0)
{
file_caricato++;
/* Apro il file in lettura */
file_input = fopen ("input.txt",
"r");
/* Se non posso aprire il file mando un messaggio di errore */
if (file_input == 0)
printf("Impossibile caricare il file.\n");
else
printf("Il file è stato caricato con successo.\n");
/* Leggo i dati e li inserisco nella struttura fino alla fine del file */
do
{
/* La funzione fscanf restituirà EOF quando avrà raggiunto la fine del file */
controllo = fscanf(file_input,
"%s %s %s %s",
nome_vino,
id_bott,
anno_prod,
luogo_imb);
/* Controllo che la variabile sia diversa da EOF per evitare che venga inserito due volte l'ultimo elemento */
if (controllo != EOF)
{
inserito = inserisci_in_lista(&testa_p,
nome_vino,
id_bott,
anno_prod,
luogo_imb);
if (inserito == 1)
{
/* Stampo i dati nel caso l'utente voglia inserirne di nuovi, rimuoverne esistenti, o ordinarli */
printf("\n%s %s %s %s",
nome_vino,
id_bott,
anno_prod,
luogo_imb);
}
}
} while(controllo != EOF);
/* Chiudo il file */
fclose(file_input);
/* Chiedo se l'utente vuole compiere altre operazioni */
printf("\n\nEseguire ulteriori operazioni? Digitare '1' in caso affermativo, '2' in caso negativo\n");
scanf("%d",
&esegui_altre_operazioni);
}
else
{
printf("Il file è già stato caricato.\n");
}
}
/* Se l'utente sceglie di inserire dei nuovi dati da tastiera */
if ((operazione == 2) && (file_caricato != 0))
{
/* Acquisisco il nome del vino */
printf("Digitare il nome del vino che si vuole inserire.\n");
scanf("%s",
nome_vino);
/* Acquisisco l'id del vino */
printf("Digitare l'id del vino che si vuole inserire.\n");
scanf("%s",
id_bott);
/* Acquisisco l'anno di produzione del vino */
printf("Digitare l'anno di produzione del vino che si vuole inserire.\n");
scanf("%s",
anno_prod);
/* Acquisisco il luogo di imbottigliamento del vino */
printf("Digitare il luogo di imbottigliamento del vino che si vuole inserire.\n");
scanf("%s",
luogo_imb);
/* Invoco la funzione per inserire i dati nella struttura */
inserito1 = inserisci_in_lista(&testa_p,
nome_vino,
id_bott,
anno_prod,
luogo_imb);
/* Se la funzione ritorna 1 significa che i dati sono stati inseriti, in tal caso... */
if (inserito1 == 1)
{
/* Messaggio di conferma */
printf("\nI seguenti dati:\n%s %s %s %s\nsono stati inseriti con successo.\n",
nome_vino,
id_bott,
anno_prod,
luogo_imb);
}
/* Chiedo se l'utente vuole compiere altre operazioni */
printf("\n\nEseguire ulteriori operazioni? Digitare '1' in caso affermativo, '2' in caso negativo\n");
scanf("%d",
&esegui_altre_operazioni);
}
if ((operazione == 3) && (file_caricato != 0))
{
printf("da fare");
}
if (operazione == 4)
{
printf("da fare");
}
} while (esegui_altre_operazioni == 1);
/*Messaggio conclusivo */
printf("Grazie per aver utilizzato il programma.\n");
return(0);
}
/* Definizione della funzione di inserimento dati in lista */
int inserisci_in_lista(lista_t **testa_p,
char nome_vino[],
char id_bott[],
char anno_prod[],
char luogo_imb[])
{
/* Dichiarazione delle variabili locali */
int inserito, /* Output: ritorna 1 se l'inserimento ha avuto successo, 0 in caso contrario */
i, /* Contatore per l'array nome_vino */
j, /* Contatore per l'array id_bott */
k, /* Contatore per l'array anno_prod */
l; /* Contatore per l'array luogo_imb */
lista_t *elem_p,
*prec_p,
*nuovo_p;
/* Ciclo che controlla se l'id del vino che viene inserito esiste già */
for (elem_p = prec_p = *testa_p;
((elem_p != NULL) && (strcmp(elem_p->id_bott, id_bott) < 0));
prec_p = elem_p, elem_p = elem_p->succ_p);
/* Se l'id è già presente */
if ((elem_p != NULL) && (strcmp(elem_p->id_bott, id_bott) == 0))
{
/* L'inserimento non avviene */
inserito = 0;
/* Messaggio di errore */
printf("Dati non inseriti.\n");
}
/* Altrimenti */
else
{
/* L'inserimento avviene */
inserito = 1;
/* Alloco memoria per il nuovo elemento che conterrà il nuovo vino */
nuovo_p = (lista_t *)malloc(sizeof(lista_t));
/* Inserisco nel nuovo elemento un puntatore all'array nuovo_vino */
for (i = 0;
i <= DIM_NOME+1;
i++);
{
nuovo_p->nome_vino[i] = nome_vino[i];
}
/* Inserisco nel nuovo elemento un puntatore all'array id_bott */
for (j = 0;
j <= DIM_ID+1;
j++);
{
nuovo_p->id_bott[j] = id_bott[j];
}
/* Inserisco nel nuovo elemento un puntatore all'array anno_prod */
for (k = 0;
k <= DIM_ANNO+1;
k++);
{
nuovo_p->anno_prod[k] = anno_prod[k];
}
/* Inserisco nel nuovo elemento un puntatore all'array luogo_imb */
for (l = 0;
l <= DIM_LUOGO+1;
l++);
{
nuovo_p->luogo_imb[l] = luogo_imb[l];
}
/* L'indirizzo dell'elemento successivo al nuovo elemento è quello corrente */
nuovo_p->succ_p = elem_p;
/* Se l'elemento è uguale alla testa */
if (elem_p == *testa_p)
/* Il nuovo elemento diventa la testa */
*testa_p = nuovo_p;
/* Altrimenti */
else
/* Il nuovo elemento diventa l'elemento successivo del precedente */
prec_p->succ_p = nuovo_p;
}
return(inserito);
}
Grazie in anticipo.