PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : std::fstream trouble


liquid
2003-05-28, 23:32:02
Hiho,

ich versuche mit Hilfe der fstream Klasse eine binäre Datei (genauer gesagt eine TGA) auszulesen.
Mein früherer TGA-Loader benutze das cstdio Interface, aber das wollte ich mal ändern. Jedenfalls scheint es so zu sein, dass er operator >> der fstream Klasse nicht so ganz funktioniert.

Das Holen von Daten aus dem stream funktioniert bei mir nur mit char bzw. unsigned chars. Nun will ich aber ein short integer mit Daten füttern.
Alles stürzt mein ganzen Code hoffnungslos, sobald ich das versuche. Es liegt allerdings nicht direkt am Einlesen, sondern daran, dass nach dem Einlesen der get-pointer des streams auf -1 gesetzt wird. Ich finde das doch reichlich merkwürdig. Die Datei ist nämlich ein wenig länger, als die paar Bytes, die er da schon eingelesen hat. Seeken, etc. funktioniert alles ohne Probleme, nur ich kriege keine Daten in Datentypen größer als ein char rein (so sieht es jedenfalls momentan aus).
Merkwürdigerweise funktioniert das alles mit dem cstdio Interface tadellos. Warum? In der Referenz steht doch ganz eindeutig, dass der operator>> mit allen C/C++ Standarddatentypen klar kommt?
Warum dann dieser Reset des get-pointers auf -1 wenn ich versuche etwas einzulesen?

cya
liquid

Demirug
2003-05-29, 11:21:37
Hast du die Datei mit ios::binary im Binar modus geöffnet?

liquid
2003-05-29, 11:59:43
void TGAFile::load(const char* const fileName)
{
if (imageData)
unload(); // unload currently loaded TGA file

// proceed with file loading

using namespace std;

ulong imageSize;
int colorMode; // 4=RGBA 3=RGB

// open targa
//ifstream _fStream(fileName, fstream::binary);
ifstream _fStream(fileName, ifstream::binary);
if (_fStream.is_open())
{
// file could be opened without error

// read first 2 bytes that we don't need
_fStream.seekg(2, ios::beg);
std::cout << "pos is: " << _fStream.tellg() << std::endl;

// read in the image type
imageTypeCode << _fStream;
//_fStream >> imageTypeCode;
std::cout << "pos is: " << _fStream.tellg() << std::endl;

// check if type is either 2 or 3 (we can handle only these two types)
if ((imageTypeCode != 2) && (imageTypeCode != 3))
{
_fStream.close();
return;
}


// image type can be handled by loader, proceed

// read 9 bytes we don't need
_fStream.seekg(9, ios::cur);
std::cout << "pos is: " << _fStream.tellg() << std::endl;

// image dimensions
//_fStream >> fstream::val;
_fStream >> imageWidth;
std::cout << "pos is: " << _fStream.tellg() << std::endl;
_fStream >> imageHeight;
std::cout << "pos is: " << _fStream.tellg() << std::endl;
//fread(&this->imageWidth, sizeof(short int), 1, filePtr);
//fread(&this->imageHeight, sizeof(short int), 1, filePtr);

// read bit-depth
_fStream >> bitCount;
std::cout << "pos is: " << _fStream.tellg() << std::endl;
//fread(&this->bitCount, sizeof(uchar), 1, filePtr);

// garbage data
_fStream.seekg(1, ios::cur);
std::cout << "pos is: " << _fStream.tellg() << std::endl;
//fread(&ucharBad, sizeof(uchar), 1, filePtr);

// colorMode (3=BGR, 4=BGRA)
colorMode = bitCount / 8;
imageSize = imageWidth * imageHeight * colorMode;

imageData = new uchar[imageSize]; // alloc mem for image data

So sieht das momentan aus. Ich hab den alten Code schon zum Teil gelöscht und auch auskommentiert.

cya
liquid

EDIT:
Ich hab jetzt nur einen Ausschnitt gepostet. imageWidth und imageHeight sind Teile von TGAFile.

liquid
2003-05-29, 16:05:56
Also ich hab das jetzt nochmal außerhalb des Projektes ausprobiert. Da gayt es auch nicht...

Also ich hab so den Eindruck, dass operator>> bei binären Files überhaupt nicht geht. Wenn ich allerdings binary-Mode abschalte, dann flippt er völlig aus und seekt wie wild durch die Datei (tellg() gibt nach dem Einlesen eines uchars Zahlen oberhalb der 3000er Grenze aus, ganz schön heftig *g*).

Mit get() und read() will ich allerdings gar nicht erst anfange, weil das Prinzip nicht besser (eher schlechter) als cstdio ist. Da muss ich dann manuell meine Datentypen casten (immer (char*)(&myData) zu tippen ist wirklich nicht toll) und außerdem (genauso wie bei cstdio) sizeof(xyz) benutzen...
Das kann doch wirklich nicht Sinn der Sache sein. Warum erfinden die sowas tolles wie operator>> und operator<< wenn man es sowieso nirgends anwenden kann. Alle Vorteile (der Operator weiß ja mit welchem Datentyp er da arbeitet, deshalb weiß er auch die Größe) sind wie weggeblasen. Naja, seis drum..

Wenn jemand noch Vorschläge hat, dann bitte posten. Vielleicht bin ich auch nur an einer kleinen Dummheit gescheitert??

cya
liquid