paco87 (Normal User)
Newbie
Messaggi: 7
Iscritto: 02/11/2011
|
ciao, ho usato la funzione seekg per una ricerca dicotomica in un file binario, solo che nn funziona. Posto solo la parte del codice relativa alla ricerca binaria,sperando in un suggerimento:
do
{
md=(sx+dx)/2;
pos=(md-1)*sizeof dipendente;
fin.clear();
fin.seekg(pos);
fin>>dipendente.ID>>dipendente.cognome>>dipendente.nome>>dipendente.cell>>dipendente.card;
if(strcmp(cognome1, dipendente.cognome)==0)
{
cout<<"\nL'elemento e' nella posizione "<<dipendente.card<<endl;
system("pause");
trovato=true;
}
else if(strcmp(cognome1, dipendente.cognome)>0)
sx = md+1;
else
dx = md-1;
}while((sx<=dx) &&(!trovato));
|
|
Pitagora (Member)
Expert
Messaggi: 367
Iscritto: 12/06/2010
|
in che senso non funziona? Cosa vuoi ottenere?
Più preciso, non chiediamo molto!
|
|
nessuno (Normal User)
Guru^2
Messaggi: 6385
Iscritto: 03/01/2010
|
A che serve la fin >> ... ?
Devi leggere il record con
fin.read
Utilizza un po' di linee di debugging (in cui visualizzi i valori di variabili importanti) per capire cosa succede durante il funzionamento del codice ...
Ultima modifica effettuata da nessuno il 02/11/2011 alle 19:54
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità. |
|
paco87 (Normal User)
Newbie
Messaggi: 7
Iscritto: 02/11/2011
|
dunque... sx e dx sono la prima e l'ultima riga del file di record, fin>> serve per leggere il record, e questa funziona perchè poi riesco a visualizzare con cout ciò che ho letto (la funzione fin.read nn mi funziona bene); il problema è che al momento di cercare un elemento, nel ciclo do while la variabile pos si posiziona sempre all'inizio dell'ultimo record fine del file. Questo è il codice completo:
#include <iostream>
#include <fstream>
using namespace std;
struct persona
{
char cognome[25];
char nome[25];
int ID;
char cell[15];
int card; //ID e card hanno lo stesso valore
}dipendente;
int main()
{
int pos;
int num_record=0;
bool trovato=false;
char cognome1[25];
int md;
cout<<"Inserisci il cognome da cercare: ";
cin>>cognome1;
ifstream fin("dip21.dat", ios::in|ios::out|ios::binary);
//ricerca binaria
while(fin>>dipendente.ID>>dipendente.cognome>>dipendente.nome>>dipendente.cell>>dipendente.card)
num_record++;
int sx=1;
int dx=num_record; //dx=6, ok
fin.clear();
do
{
md=(sx+dx)/2;
pos=(md-1)*sizeof dipendente;
fin.clear();
fin.seekg(pos);
fin>>dipendente.ID>>dipendente.cognome>>dipendente.nome>>dipendente.cell>>dipendente.card;
cout<<dipendente.ID<<" "<<dipendente.cognome<<" "<<dipendente.nome<<" "<<dipendente.cell<<" "<<dipendente.card<<endl;
if(strcmp(cognome1, dipendente.cognome))
{
cout<<"\nL'elemento e' nella posizione "<<dipendente.card<<endl;
system("pause");
trovato=true;
}
else if(strcmp(cognome1, dipendente.cognome)<0)
dx = md-1;
else
sx = md+1;
}while((sx<=dx) &&(!trovato));
if(trovato==true)
cout<<"\nL'elemento e' stato trovato ";
else
cout<<"\nElemento non trovato!\n";
fin.close();
system("pause");
return 0;
}
|
|
nessuno (Normal User)
Guru^2
Messaggi: 6385
Iscritto: 03/01/2010
|
Questa linea
while(fin>>dipendente.ID>>dipendente.cognome>>dipendente.nome>>dipendente.cell>>dipendente.card)
num_record++;
non funziona e num_record vale 0 (controlla con un po' di debugging).
Per trovare il numero dei record devi utilizzare la funzione tellg dividendo il risultato per la sizeof della struttura.
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità. |
|
paco87 (Normal User)
Newbie
Messaggi: 7
Iscritto: 02/11/2011
|
scusami, io ho provato a vedere quanto vale num_record ed è giusto, è esattamnte il numero di record del file(per me 6, l'ho anke scritto nel commento); ho provato anche a visualizzare per ogni ciclo i valori di sx,dx e md e sono corretti; il problema è che la funzione seekg non si posiziona sul record con il numero md, neanche dopo fin.clear()!!
|
|
nessuno (Normal User)
Guru^2
Messaggi: 6385
Iscritto: 03/01/2010
|
C'è un equivoco di fondo ... tu stai utilizzando un approccio di lettura/scrittura di record (usando la struttura e la seek).
Con questo approccio devi usare la read e la write e non >> e << per leggere scrivere.
Scrivendo il file con la write e leggendolo con la read (ripeto, dato che usi la seek per posizionarti), non vedo problemi.
Al contrario, se scrivi il file con la write, non otterrai il valore corretto in num_record. Se hai scritto il file in precedenza senza la write, ogni record potrebbe avere lunghezza diversa da quella che ti attendi con la seek.
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità. |
|
paco87 (Normal User)
Newbie
Messaggi: 7
Iscritto: 02/11/2011
|
Ti ringrazio innanzitutto per le tue risposte; il fatto è che i record hanno tutti la stessa lunghezza, dato che l'ho impostata con il metodo setw, la file.read nn riesce a leggermi tutto il record, e quando faccio una cout a video mi stampa metà record. Inoltre se leggo con fread e stampo a video il campo card nn vedo effettivamente il campo della struttura, ma un numero grandissimo.
|
|
nessuno (Normal User)
Guru^2
Messaggi: 6385
Iscritto: 03/01/2010
|
Postato originariamente da paco87:
il fatto è che i record hanno tutti la stessa lunghezza |
Presupposto della seek è che i record *abbiano* la stessa lunghezza (in particolare la lunghezza è sizeof(dipendente) che tu usi nel tuo codice).
la file.read nn riesce a leggermi tutto il record |
Se hai scritto il record con la file.write allora la file.read lo leggerà correttamente dopo essersi posizionata con la seekg.
Se scrivi il file in un altro modo, non puoi pretendere che la file.read funzioni (e tanto meno la seek)
Tutti problemi legati al fatto che non hai scritto/letto con lo stesso metodo.
Se usi >> e << allora utilizza un file sequenziale. Altrimenti usi write, read e seek. Non un miscuglio.
Adesso, cancella il file, riscrivilo usando unicamente la write e rileggilo usando unicamente la read (e la seekg) e vedrai che funzionerà. Ultima modifica effettuata da nessuno il 03/11/2011 alle 16:23
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità. |
|