PDA

Visualizza versione completa : [C] Operazioni sui file a basso livello


UG0_BOSS
31-10-2006, 22.19.33
Ormai sono sempre qua a chiedere... Ma checcepossofà? siete sempre così pronti e disponibili... :inn:


Allora... Ho un file (binario) che uso a mo' di database; ogni serie di dati occupa 150 byte.

In questo modo, se ad esempio voglio leggere i dati memorizzati nel quarto "indice" mi basta spostare l'indicatore di posizione di 150 * 4 byte rispetto all'inizio del file.

Il problema è che sarebbe necessaria un'opzione per eliminare un record, quindi "spostare" tutti i bit contenuti al suo interno verso sinistra di 150 byte, a partire da un certo punto.

Ho pensato che forse nell' I/O low-level c'è una funzione apposita (come negli operatori sui bit, che però agiscono solo sulle variabili in memoria, da quel che ho capito). Se la mia intuizione è giusta, mi potreste gentilmente illuminare?

ancora grazie :)

UG0_BOSS
01-11-2006, 00.55.32
update: ok, senza usare funzioni di low-level I/O ce l'ho fatta :).

Unico problema: non riesco a cancellare la parte finale del file: ad esempio, se cancello il record numero 11, slittano tutti a sx ma l'ultimo indice viene "raddoppiato".

PRIMA:
1. Aldo
2. Beppe
3. Carlo
4. Dario
5. Ernesto

elimina Carlo;

1. Aldo
2. Beppe
3. Dario
4. Ernesto
5. Ernesto


Come faccio a "tagliare" gli ultimi 150 byte del file? devo per forza salvare su un nuovo file, cancellare quello vecchio e rinominare? certo che no (spero).

Semi.genius
01-11-2006, 09.57.17
Stai attento..se è come penso io e hai usato FEOF per controllare la fine del file, a volte non funziona "la prima volta"...dovresti fare un doppio controllo di EOF all'interno del ciclo con una if

UG0_BOSS
01-11-2006, 18.05.33
No no il problema non sta nella stampa dei dati, basta guardare la dimensione del file per capirlo. Il problema sta nel riuscire a ridurre la dimensione del file.

Semi.genius
01-11-2006, 18.56.38
Hai usato delle operazioni di scrittura a blocchi? (per intenderci hai usato funzioni come fwrite e fread)Bisognerebbe dare un occhiata al codice per capire meglio

UG0_BOSS
01-11-2006, 19.09.02
ecco questa è la parte di codice rilevante


// Eliminazione dei dati ///////////////////////////////////////////////////////
else if( scelta == 3 ){

printf("\n\n Quale indice vuoi eliminare? \n");
scanf("%d", &index);

// apre il file
if ((File = fopen("voti.smm", "r+b")) == NULL){
printf("\n \n Errore apertura file in scrittura \n \n");
fflush(stdin);
getchar();
return 104;
}

do{
// Sposta l'indicatore dopo la traccia da eliminare
fseek(File, (DIMENSIONEINDEX * (index)), SEEK_SET);

// Legge tutti i dati del record e li memorizza.
fread(&Voto, sizeof Voto, 1, File);
fread(&Materia, sizeof Materia, 1, File);
fread(&DataVoto, sizeof DataVoto, 1, File);
fread(&DataProva, sizeof DataProva, 1, File);
fread(&Descrizione, sizeof Descrizione, 1, File);
fread(&Tipo, sizeof Tipo, 1, File);

// Sposta l'indicatore sulla traccia da eliminare
fseek(File, (DIMENSIONEINDEX * (index - 1)), SEEK_SET);

// Scrive tutti i dati sulla traccia precedente
fwrite(&Voto, sizeof Voto, 1, File);
fwrite(&Materia, sizeof Materia, 1, File);
fwrite(&DataVoto, sizeof DataVoto, 1, File);
fwrite(&DataProva, sizeof DataProva, 1, File);
fwrite(&Descrizione, sizeof Descrizione, 1, File);
fwrite(&Tipo, sizeof Tipo, 1, File);

index++;
}
while(index != (indexmax+1) );

// Chiude il file.
if(fclose(File) != 0){
return 114;
}

}

Semi.genius
01-11-2006, 20.17.32
(a parte che se il file fosse vuoto farebbe errore il programma)
LA cancellazione così non va bene..

ammettiamo che hai questi 5 valori (non metto i nomi tanto si capisce comuqnue):
1 2 3 4 5

vuoi cancellare il 3... il tuo programma salva il 4 e lo scrive nel 3, quindi hai
1 2 4 4 5

l'indice adesso si trova sulla posizione 5 e procedendo come prima hai la situazione

1 2 4 5 5
ma non hai più la possibilità di cancellare l'ultimo 5.
Se hai capito, l'errore ti posso suggerire come risolverlo ma preferisco dirtela se hai capito cosa intendo e non riesci a farlo:p

UG0_BOSS
01-11-2006, 20.33.02
ah è vero :cool:

adesso provo a correggere... poi ti so dire

Semi.genius
01-11-2006, 20.41.39
Fai fai...così nel frattempo scopro perché Antivir mi rileva come virus un mio programma per controllare le simmetrie di una matrice :o

UG0_BOSS
01-11-2006, 21.09.01
uhm... però se il programma si fermasse prima di posizionarsi sul quinto indice poi come faccio a cancellare quello che viene dopo?

UG0_BOSS
03-11-2006, 17.25.25
up! (Y)

UG0_BOSS
06-11-2006, 22.08.35
ari-uppete! (Y)

Semi.genius
06-11-2006, 22.28.43
Scusa...ma sono mezzo stravolto per l'università...comunque, per risolvere, dovresti fare un accesso diretto (per intenderci rw+) e spostarti all'inizio dell'ultimo, scrivere un EOF e chiudere il flusso...non sono sicuro perché non l ofaccio da molto ma magari basta

UG0_BOSS
08-11-2006, 21.14.02
Scusa...ma sono mezzo stravolto per l'università...

don't worry :)

per scrivere l'EOF come faccio? ho provato a scrivere un carattere con valore -1 ma non funge :confused:

Semi.genius
09-11-2006, 20.32.44
PRova a dare un occhiata a questa discussione http://www.p2pforum.it/forum/archive/index.php/t-50845.html

UG0_BOSS
09-11-2006, 22.13.56
da quel che ho letto mi sembra che il metodo più semplice e adatto su tutte le piattaforme sia la creazione di un file temporaneo, perciò prenderò questa via, dato che è un'idea che avevo già avuto in precedenza ma credevo fosse evitabile.

A questo punto posso dichiarare risolta la questione. Ti ringrazio per il tempo dedicatomi :)