Fájlkezelés (C++)

 ( pgee | 2006. május 13., szombat - 13:19 )

Sziasztok!

Azt hiszem valamit félreértettem...
Adott a következő tag-függvény:

void CKeszlet::Lista()
{
KESZLET adat;

this->in_file.open(this->filename.c_str(), ios_base::in);
this->in_file.read((char*)&adat, sizeof(KESZLET));
cout << this->filename << endl << "Azonosito \tKeszlet" << endl;
while(!this->in_file.eof())
{
cout << adat.azon << "\t\t" << adat.keszlet << endl;
this->in_file.read((char*)&adat, sizeof(KESZLET));
}
this->in_file.close();
}

Ha, kétszer egymás után hívom meg ugyanarra, vagy más fájlra (más fájl esetén this->filename változik, de ugyanaz az objektum), akkor a második lefutásnál üres a fájl. Ez miért van így???

Előre is köszi!

pgee

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Hát így elsőre a készlet nem tudom milyen tipus, de ha nem egy srtuct vagy char akkor hibás az olvasás. Ha a készlethez megírod a << és a >>operatort, akkor basic_ostream és basic_istremmel kényelmesen lehetne használni. pl infile>>adat,outfile< A fájl üres, vagy a beolvasott adat nem lászik
vagyis a ciklus egyből leáll vagy fut csak nincs adat az adatban?
--
A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station

A KESZLET struct. És maga a függvény első lefutásnál helyes eredményt ad, de a másodiknál már rögtön a fájl nyitás után igaz az in_file.eof()... Ha ujrainditom a programot, akkor pedig elsőre megint helysen listáz, tehát a fájl nem üres, a ciklus egyből leáll.
--------------------
Powered by Ubuntu 5.10

milyen struct?
én egy buffer owerflovra tippelnék
vagy vágd be a teljes forrást az talán segythet
--
A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station

Csak egy kis részlet:

#include
#include
#include

using namespace std;

typedef struct
{
int azon;
long keszlet;
} KESZLET;
...
class CKeszlet
{
private:
string filename;
ifstream in_file;
ofstream out_file;
public:
CKeszlet(const string filename);
void Feltolt();
void Lista();
void FilenevCsere(const string filename);
void Nyit();
void Zar();
void NyitIr();
void ZarIr();
void Olvas(STATUSZ &sx, KESZLET &dx);
void Ir(KESZLET dx);
};
...

int main(int argc, char *argv[])
{
CAdatbazis* adatb;
adatb = new CAdatbazis(filename1,filename2);
adatb->ListaAdat();
adatb->ListaAdat();
char ch; cin >> ch;

delete adatb;
return 0;
}

A CAdatbazis class van egy CKeszlet típusú változója, és ListaAdat() ennek az objektumnak a Lista függvényét hivja meg.

Ebben a formában elvileg kétszer lenne kilistázva ugyanaz, a fejléc meg is jelenik kétszer, de második után már nincs semmi...

--------------------
Powered by Ubuntu 5.10

Akkor már csak a bementei adatok formátuma az érdekes.
ha így olvasod be a fájlt akkor:
int mérete 4 byte
long mérete 4 byte
Tehát a fájlodban elvileg 4bytonként van egy szám,de ugye binárisan. Mindenféle konverzió nélkül olvasod fel char[8]at castolod 2 számmá.
ha nem akkor itt bug van
ha szovegként írtad bele a számokat
1 2.2
3 4.5
formában akkor inkább így kellen csinálni:
in_file>>adat.azon;
in_file>>adat.keszlet;
ekkor a konverzió megtörténik

---
A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station

A fájlbaírás így történt:
out_file.write((char*)&adat, sizeof(KESZLET));
Ahol adat KESZLET típusú
--------------------
Powered by Ubuntu 5.10

Statikus az objektumod, amikor újra megnyitod valószínűleg a pointer még mindíg a fájl végére mutat, ha dinamikus lenne a in_file, ez nem lenne gond.
rdbuf fv-el lehet lekérdezni a filebuf-re mutató pointert.
vagy próbálj open után egy seeket a fájl elejére.
---
A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station

Próbáltam seekelni, de az sem működött...
infile.seekg(ios::beg);

Ígyhát dinamikus lett az in_file. A probléma megoldódott.

De még mindig nem értem miért volt gond. Valószínű a filemutató a fájl végén maradt zárás, majd újbóli nyitás után. Ez így normális?
--------------------
Powered by Ubuntu 5.10

nem nem igazán, opennél előre kellene állni.
lehet hogy bugos a stl-amit használsz.
--
A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station

Szerintem mivel C++-ban programozol, ezért érdemes lenne a következő módon beolvasnod:
#include < fstream >
...
KESZLET e;
ifstream filein(this->filename.c_str(),ios::in);
filein >> e;
...
filein.close();

Persze ekkor implementálnod kell a KESZLET operator<< és operator>> -ját is.

egyrészt túlolvasod a file-t. olvasnál belőle sizeof(KESZLET) byte-ot, de már nincs benne. ilyenkor az eof biten kívül a fail bit is beállítódik, ami mindössze 'nem szép'.
ami viszont a problémát okozza, az az, hogy ha újranyitod a stream-et, akkor clear()-elni kéne, mert az eofbit már legalább be van állítva, és eof-os file-ból olvasni fail.
-
mondjuk a this-t nem lenne muszáj kiírni, de egy ilyen sort írj az open elé:
this->in_file.clear();