06. maj 2003 - 17:41Der er
11 kommentarer og 1 løsning
fstream filproblemer ...
Hej,
jeg har en klasse med en fstream som privat medlem. Med denne åbner jeg en fil i random access mode ( ios::in | ios::out | ios::binary ). Hvis jeg nu skriver nogle data til filen, og derefter prøver at læse dem igen, sker der nogle gange det, at det ikke er de samme data, der læses, som jeg har skrevet.
Det vidste jeg egentlig godt - ville bare lige se om der var nogen der havde en anelse om problemet, før jeg fyldte et spørgsmål op med masser af kode.
Her er de 2 funktioner i klassen, som hhv. skriver og læser til/fra filen. Filen åbnes i klassens constructor. filIO objektet går ikke nødvendigvis ud af scope mellem 2 eller flere kald til editData eller getData - så filen lukkes altså ikke mellem læsning og skrivning:
bool filIO::editData(entry ent) { if ( ent.ID > MAX_USERS - 1 || ent.ID < 0 ) // Vi kan ikke skrive på en plads > 99 return false ;
if ( *(ent.name) == 0 ) // opdater places - array places[ent.ID] = true ; // (Hvis første plads i ent.name = 0, else // er pladsen nu ledig) places[ent.ID] = false ;
data.seekp(ent.ID * REC_LEN); // Find den plads, der skal skrives på.
bool filIO::getData(const int ID,entry * ent) { char tmp[2] ; if ( ID < 0 || ID > MAX_USERS - 1 ) return false ;
ent->ID = ID ; data.seekg(ID * REC_LEN + 2) ; // Find det sted, navnet begynder. data.read(ent->name,30) ; // Læs navn ent->name[30] = 0 ; // Sørg for at navn er termineret med 0.
data.read(tmp,2) ; // Læs kode // De 2 læste bytes står i 'forkert rækkefølge', de konverteres til int: if ( tmp[0] < 0 ) ent->code = ((tmp[1]+1) * 256) + tmp[0] ; else ent->code = tmp[1] * 256 + tmp[0] ;
data.read(tmp,2) ; // Læs kort // De 2 læste bytes står i 'forkert rækkefølge', de konverteres til int: if ( tmp[0] < 0 ) ent->card = ((tmp[1]+1) * 256) + tmp[0] ; else ent->card = tmp[1] * 256 + tmp[0] ;
data.read(&ent->status,1) ; // Læs status if ( *(ent->name) == 0 ) return false ; else return true ; }
1) Virker direkte, hvilket gør 2) overflødig - så nu er koden blevet lidt mere simpel, tak. En lidt mere intensiv test i morgen vil så vise, om problemet med at den læser forkerte data i visse tilfælde, også er væk.
Til re 2) : Er det korrekt forstået, at << operatoren her roterer bits'ne i tmp[1] 8 pladser til venstre, således at værdien kan or'es direkte med tmp[0] for at danne tallet ? Vil sådan et statement fungere - her tænker jeg på, at tmp[1] som udgangspunkt jo kun består af 8 bits - vil << operatoren så bevirke, at værdien udvides til en 16 bits værdi ?
Der er stadig problemer. Jeg bruger kun de 2 ovenfor viste funktioner til at skrive / læse i filen. Alligevel sker det, at der bliver skrevet forkert til filen. Helt konkret, i linien data.write(reinterpret_cast<const char *>(&ent.ID),2) ;
Her sker der, såvidt jeg kan se, det at der bliver skrevet 3 bytes i.s.f 2 i nogle tilfælde (ikke altid, hvilket gør problemet endnu mere mystisk). I hvert fald udmønter fejlen sig i, at første plads i ent.name bliver 0, når jeg bruger filIO::getData til at læse dataene igen.
Jeg håber, det gav mening, og at der er nogen der har en ide om hvad jeg gør galt.
arne_v >> Under alle omstændigheder falder der en flok point af til dig for hjælpen indtil videre.
Giver samme problem. Jeg har nu identificeret problemet så langt, at hvis en datapost gemmes med ID = 10, så opstår problemet => Første plads i navn bliver 0 når post 10 læses igen. Problemet har også været der med andre ID numre, men i øjeblikket opstår fejlen konsekvent på ID 10. Problemet er aldrig opstået ved ID numre mindre end 10.
Problemet er der stadig. Jeg lukker spørgsmålet, men hvis der er nogen der har en idé til afhjælpning af problemet, så skriv endelig ;-) Der er 200 point til den der finder en løsning ;-)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.