PDA

Visualizza la versione completa : [C] Lettura/Scrittura File Binari


kry87
18-09-2014, 17:18
Ciao ragazzi , vi scrivo per chiedervi aiuto.
Ho la necessità di realizzare una funzione che sia in grado di inserire ciclicamente all'interno di un file binario la seguente struttura:
struct Record{
char str[30];
int n;
}
str è una sequenza di 30 caratteri che possono essere solamente 0,1,2 , n ovviamente un intero che tiene traccia del numero di volte che ho tentato di inserire una sequenza simile.
Ho deciso di utilizzare il file con accesso causale così da poter avere un accesso diretto ad ogni struttura inserita.

Ogni volta che devo inserire una struttura genero una chiave valutando in base 3 str ed arrotondando al primo multiplo di 36 prossimo alla chiave generata ( 36 in quanto sizeof(struct ...) è proprio 36).
Mi posiziono con fseek(fp,key,SEEK_SET) ,leggo con fread(recordtest, sizeof(struct), 1, fp) se in quella posizione c'è già un campo con la stessa chiave,
se sì aggiorno n(contatore) altrimenti mi riposiziono con fseek e scrivo con fwrite(record,sizeof(struct),1,fp) in quella posizione.

Purtroppo non funziona, non riesco a capire se sia perchè le chiavi generate siano numeri troppo grandi, considerato che il numero massimo è 3^30 -1 oppure faccio caos nel posizionarmi all'interno del file.

oregon
18-09-2014, 20:37
Posta il codice che hai usato e ne parliamo.

kry87
18-09-2014, 21:04
Sì scusami.

Codice :

typedef struct record
{
char code[DAY+1];
int occ;
}Record;

void saveRecord(char *nomeFile,Record *vrecord)
{
long long int key;
int i;
FILE *fp;
fp = fopen(nomeFile,"wb");
if(fp==NULL)
return;
for(i = 0; i < Nrecord ; i++)
{
key = hash(vrecord[i].code);
fseek(fp,key,SEEK_SET);
fwrite(&vrecord[i],sizeof(Record),1,fp);
}
fclose(fp);
return;

}
long long int hash(char *vett)
{
long long int i,c;
long long int mod;
long long int key=0;
for(i=DAY-1;i>=0;i--)
{
c =(int)vett[i]-48;
key += pow(3,DAY-1-i)*c;
}
mod = key%36;
if(mod>0)
{
mod = 36-mod;
key+=mod;
}
return key;

}

oregon
18-09-2014, 21:24
Ovviamente 3^30 è veramente troppo e quindi devi rivedere il calcolo della chiave ... (non so esattamente a cosa ti serva ma il metodo non è applicabile).

kry87
18-09-2014, 21:36
La stringa all'interno della struttura contiene una sequenza di 0,1,2 quindi mi è molto comoda quella funzione di hash perchè non mi darà mai due chiavi uguali. Non esiste una fseek che lavori su un long long ?

oregon
18-09-2014, 21:46
Il problema è che così potresti avere un file di

7.412.080.755.407.364 (!)

byte (ovvero più di 7000 TB) non gestibile in molti casi.

Comunque, esiste la fseek64 ... dipende dal compilatore/sistema.

kry87
18-09-2014, 22:03
Decisamente non gestibile :confused: non avevo considerato questo aspetto.
Tenendo conto che le combinazioni possibili di cui devo tenere traccia sono 205.891.132.094.648 , quale sarebbe una soluzione conveniente?

oregon
18-09-2014, 22:25
Date le premesse, non mi pare ci sia soluzione. Se la necessità è di memorizzare *tutti* i dati, questi sono decisamente troppi.

Se i dati da memorizzare sono in numero comunque limitato, puoi generare una chiave con un algoritmo e gestire le collisioni.

kry87
18-09-2014, 22:31
Ma in quale struttura? sempre in un file ?
Anche gestendo le collisioni la dimensione massima nel caso siano presenti tutte le sequenze sarebbe quella giusto?

oregon
18-09-2014, 23:11
Infatti ti ho scritto

Se la necessità è di memorizzare *tutti* i dati, questi sono decisamente troppi.

e non c'è soluzione.

Loading