Ciao ragazzi,
dispongo di un file di testo contenente alcune informazioni(codice prodotto, codice categoria, descrizione, numero, costo) su 3 prodotti cosi fatto:
codice:
A451XXCAT001
PASTA CONF. 1KG
100
99.0
A451XY
CAT002
MAGLIA LANA
25
6.70
A452XX
CAT001
SUGO
33
9.99
Devo scrivere una funzione che dopo aver letto ciascun prodotto dal file, lo memorizzi in una lista ordinata mediante il codice prodotto. Tale funzione è la seguente:
codice:
int carica_lista(char fName[], listaP *l) { tipoBaseLista prodotto;
int n = 0;
char buf[D] = {0};
listaP pCorrente; /* puntatore usato per la scansione */
listaP pNodo; /* puntatore di servizio temporaneo */
listaP pPrec; //puntatore al nodo precedente
FILE *f;
f = fopen(fName, "r");
if (f == NULL) {
printf("Non e' possibile aprire il file\n");
exit(1);
}
pNodo = malloc(sizeof(prodotto));
pCorrente = NULL;
//Per leggere una riga per volta dal file basta usare la funzione fget. Mentre invece, con la funzione sscanf formatto la riga in base al tipo di dato.
while (!feof(f)) {
printf("\nInizio while %d\n", n+1);
fgets(buf, sizeof(buf), f);
strcpy(prodotto.codP, buf);
fgets(buf, sizeof(buf), f);
strcpy(prodotto.codC, buf);
fgets(buf, sizeof(buf), f);
strcpy(prodotto.descr, buf);
fgets(buf, sizeof(buf), f);//lettura del numero dei prodotti
sscanf(buf, "%d", &prodotto.num);
fgets(buf, sizeof(buf), f);//lettura del costo del prodotto
sscanf(buf, "%f", &prodotto.costo);
pNodo->info = prodotto;
pNodo->next = NULL;
/* scansione della lista*/
if (*l == NULL){//Se la lista è vuota
printf("\nEntrato1\n");
*l = pNodo;
}
else if(strcmp(prodotto.codP, (*l)->info.codP) < 0){//se il nuovo nodo deve diventare il nodo testa
printf("\nEntrato2\n");
pNodo->next = *l; //salvo il vecchio nodo testa
*l = pNodo; //valorizzo il nodo testa con il nuovo nodo inserito
(*l)->next = pNodo; //collego il nuovo nodo testa con il vecchio
}
else{//se il nuovo nodo deve essere inserito dopo il nodo testa
printf("\nEntrato3\n");
pCorrente = *l; //inizializzo il nodo che serve per la scansione con il nodo testa.
/*NEL SECONDO CICLO WHILE pCORRENTE PUNTA AL SECONDO PRODOTTO INSERITO. PERCHE'??*/
while (pCorrente->next != NULL && strcmp(prodotto.codP, pCorrente->info.codP) > 0){//scansiono la lista finchè il nodo corrente punta ad un elemento non NULL e finchè il prodotto da inserire non ha un codice prodotto inferiore a quello del nodo corrente
printf("\nEntrato4\n");
pPrec = pCorrente;
pCorrente = pCorrente->next;//assegno a pCorrente il riferimento del nodo successivo
}
/* concatenazione del nuovo record */
if(strcmp(prodotto.codP, pCorrente->info.codP) < 0){//inserimento non in coda alla lista
printf("\nEntrato5\n");
pNodo->next = pCorrente;//collegamento tra il nuovo nodo e il suo successivo
pPrec->next = pNodo;//collegamento tra il nodo precedente e quello nuovo
}
else if(pCorrente->next == NULL) {//inserimento in coda alla lista
printf("\nEntrato6\n");
pCorrente->next = pNodo;//collegamento della coda della lista al nuovo nodo
}
}
printf("\nFine while %d\n", n+1);
n++;
}
fclose(f);
return n;
system("PAUSE");
}
Tale funzione presenta un'anomalia nell'else commentato con "se il nuovo nodo deve essere inserito dopo il nodo testa": nel secondo ciclo while, pCorrente (e quindi anche il nodo testa l), dopo essere stato inizializzato con il nodo testa (pCorrente = *l, assume erroneamente il valore del secondo prodotto. Dopo svariate letture del codice non sono riuscito a capire qual è la causa del problema .
Per completezza posto pure la struttura della lista:
codice:
typedef struct { char codP[C];
char codC[C];
char descr[D];
int num;
float costo;
} tipoBaseLista;
typedef struct nodoLista{
tipoBaseLista info;
struct nodoLista *next;
}prodotto;
typedef prodotto *listaP;
e il main
codice:
int main() { char filename[] = "Magazzino.txt";
listaP lista = NULL;//Creo una lista vuota
printf("\nNumero prodotti caricati: %d\n", carica_lista(filename, &lista));
return 0;
system("PAUSE");
}
Qualcuno mi potrebbe aiutare?
Grazie in anticipo,
mbistato