PDA

Visualizza la versione completa : [C++] File e Struct


zaltar
25-01-2003, 12:50
Ho una domandina su File e Strutture.
In realtà è più una curiosità: :gren:

Ho memorizzato su un file binario una specie di database, costruito ovviamente tramite struct. Per coloro che si stanno già preoccupando preciso che sono liste semplici, non dinamiche.
Il problemino è questo: :confused:
quando visualizzo la lista di tutti i record inseriti in precedenza (operazione resa possibile grazie all'append binario) l'ultimo record, qualunque esso sia, viene stampato a video due volte.
Qualcuno sa dirmi perchè? e come ovviare all'inconveniente? :smack:

Grazie, Zaltar.

Al è qui
26-01-2003, 10:47
Non hai il codice?

zaltar
27-01-2003, 13:27
Sono riuscito a risolvere il problema, tuttavia non ho capito per quale ragione si verifica.

Si tratta di un programma per gestire una videoteca, preciso che non è ancora concluso quindi sono presenti errori, non farci caso:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ncar 15
#define dim 3

typedef struct{
char codice[ncar];
char titolo[ncar];
char attori[ncar];
int durata, anno, copiedisp, copienol, noleggi;
} movie;

FILE *fp=NULL;
char cod[ncar];

void ins(movie *temp) {
int *z;

printf("\nInserisci il codice: ");
fflush(stdin);
scanf("%s", temp->codice);
printf("\nInserisci il titolo: ");
fflush(stdin);
scanf("%s", temp->titolo);
printf("\nInserisci gli attori: ");
fflush(stdin);
scanf("%s", temp->attori);
printf("\nInserisci la durata: ");
fflush(stdin);
scanf("%d", z);
temp->durata=*z;
printf("\nInserisci il anno: ");
fflush(stdin);
scanf("%d", z);
temp->anno=*z;
printf("\nInserisci il numero di copie disponibili: ");
fflush(stdin);
scanf("%d", z);
temp->copiedisp=*z;
printf("\nInserisci il numero di copie noleggiate: ");
fflush(stdin);
scanf("%d", z);
temp->copienol=*z;
printf("\nInserisci il numero totale di noleggi: ");
fflush(stdin);
scanf("%d", z);
temp->noleggi=*z;
fp=fopen("video.bin", "ab");
fwrite(temp, sizeof(movie), 1, fp);
fclose(fp);
}

void show(movie *temp) {
printf("\n\nCodice: %s", temp->codice);
printf("\tTitolo: %s", temp->titolo);
printf("\tAttori: %s", temp->attori);
printf("\tDurata: %d", temp->durata);
printf("\tAnno: %d", temp->anno);
printf("\tCopie disponibili: %d", temp->copiedisp);
printf("\tCopie noleggiate: %d", temp->copienol);
printf("\tTotale noleggi: %d.", temp->noleggi);
}

void nol() { /* Non l'ho ancora sistemata */
movie *pfilm, *temp;
long pos;

fp=fopen("video.bin", "rb+");
while (fread(pfilm, sizeof(movie), 1, fp)!=0) {
fread(temp, sizeof(movie), 1, fp);
if (strcmp(temp->codice, cod)) {
temp->copiedisp=(temp->copiedisp)-1;
temp->copienol=(temp->copienol)+1;
fseek(fp, -(sizeof(movie)), SEEK_CUR);
fwrite(temp, sizeof(movie), 1, fp);
break;
}
}
fclose(fp);
}

void main() {
movie film;
int op;
long inizio, fine;

clrscr();
while (op!=6) {
printf("\n\nLe operazioni disponibili sono: ");
printf("\n1 - Inserire un film.");
printf("\n2 - Vedere la lista dei film.");
printf("\n3 - Memorizzare un noleggio.");
printf("\n4 - Restituire un film.");
printf("\n5 - Cancellare la lista dei film.");
printf("\n6 - Uscire.");
printf("\nQuale operazione vuoi eseguire? ");
scanf("%d", &op);
switch (op) {
case 1: ins(&film);
break;
case 2:
/* Questo è il punto in questione! */
-----------> fp=fopen("video.bin", "rb");
fseek(fp, 0, SEEK_END);
fine=ftell(fp);
inizio=0;
while (inizio<fine) {
fseek(fp, inizio, SEEK_SET);
fread(&film, sizeof(movie), 1, fp);
inizio=ftell(fp);
show(&film);
}
fclose(fp);
------------> break;
case 3: printf("\nSpecifica il codice: ");
scanf("%s", &cod);
nol();
printf("\nNoleggio Memorizzato.");
break;
case 5: remove("video.bin");
printf("\nLista Cancellata.");
break;
case 6: printf("\nProgramma Terminato.");
break;
}
}
} /* Fine del Programma */

Nella zona evidenziata ho risolto in quella maniera lo scorrimento del file con corrispondente stampa a video dei valori. :gren:
Ora, da quello che so dovrebbe essere molto più semplicemente utilizzata un (feof(fp)!=0) o (!feof(fp)), il fatto è che in questo modo l'ultimo record viene stampato a video 2 volte. :jam:
Sembra una vakkata da niente ma quando cominci a maneggiare diverse volte le informazioni presenti sul file estrapolandole dopo aver scorso il file con feof ti ritrovi ad una crescita esponenziale del bug. :nonono:
Ho anche provato a scorrere il file ponendo la condizione fread(fp, sizeof(movie), 1, fp)!=NULL e fread(...)!=0 però venivano visualizzati solo gli ultimi record sebbene il file contenesse tutti quelli inseriti dall'utente. :eek:

Non riesco a capire perchè il codice evidenziato funziona mentre gli altri metodi falliscono miseramente. :zamm:

Qualche idea? :confused:

Ciao, Zaltar.

Loading