Thread: Structures and stream reads

  1. #1
    Registered User
    Join Date
    Apr 2002
    Posts
    23

    Structures and stream reads

    Hi,
    I'm having trouble understanding a problem I came across when trying to read a bitmap header into a structure. I thought it was possible to read the header straight into a structure using the 'sizeof' function on the structure:

    Code:
    #include <iostream.h>
    #include <fstream.h>
    
    struct HEADER {
    	unsigned short bftype;
    	unsigned int bfsize;
    	unsigned short res1;
    	unsigned short res2;
    	unsigned int offset;
    };
    
    int main(void)
    {
    	
    	ifstream tester ("abitmap.bmp",ios::in|ios::binary);
    
    	HEADER bmfh;
    
    
    	tester.read((char *)&bmfh,sizeof(bmfh));
    
    	cout << "Bitmap file header contents" << "\n"
    		 <<"bftype = " << bmfh.bftype << "\n"
    		 <<"bfSIZE = " << bmfh.bfsize << "\n"
    		 <<"bfReserved1 = " << bmfh.res1 << "\n"
    		 <<"bfReserved2 = " << bmfh.res2 << "\n"
    		  <<"bfOffbits = " << bmfh.offset << "\n \n \n";
    
    	return 1;
    }
    However, with this code the header was is not read in properly. I remember reading somewhere that elements in structures such as 'shorts' may fill more space in the structure than neccessary and believe this may be what is causing the problem. Is there any 'nice' way to solve this problem using a similar method to:

    tester.read((char *)&bmfh,sizeof(bmfh));

    I managed to read the header in using individual reads on each element is not very 'nice':

    Code:
    #include <iostream.h>
    #include <fstream.h>
    
    struct HEADER {
    	unsigned short bftype;
    	unsigned int bfsize;
    	unsigned short res1;
    	unsigned short res2;
    	unsigned int offset;
    };
    
    int main(void) 
    {
    	ifstream tester ("abitmap.bmp",ios::in|ios::binary);
    	if(!tester){
    		cout<<"Cannot read from file";	
    		return 0;
    	}
    	unsigned short bftype;
    	unsigned int bfsize;
    	unsigned short res1;
    	unsigned short res2;
    	unsigned int offset;
    	tester.read((char*) &bftype,sizeof(bftype));
    	tester.read((char*) &bfsize,sizeof(bfsize));
    	tester.read((char*) &res1,sizeof(res1));
    	tester.read((char*) &res2,sizeof(res2));
    	tester.read((char*) &offset,sizeof(offset));
    	
    	cout << "Bitmap file header contents" << "\n"
    		 <<"bftype = " << bftype << "\n"
    		 <<"bfSIZE = " << bfsize << "\n"
    		 <<"bfReserved1 = " << res1 << "\n"
    		 <<"bfReserved2 = " << res2 << "\n"
    		  <<"bfOffbits = " << offset << "\n \n \n";
    
    		return 1;
    }
    thanks for any help,

    brif
    Last edited by brif; 08-16-2002 at 07:44 AM.

  2. #2
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    you're structure seems to be defined correctly if long and int are the same on your system. the two elements in BITMAPFILEHEADER that are DWORD are unsigned long
    Code:
    typedef struct tagBITMAPFILEHEADER {
            WORD    bfType;
            DWORD   bfSize;
            WORD    bfReserved1;
            WORD    bfReserved2;
            DWORD   bfOffBits;
    } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
    That doesn't seem like it is a good answer but it is something I notice as different.

    You're byte boundary of a struct idea might be right though.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  3. #3
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784

    Re: Structures and stream reads

    Originally posted by brif

    Code:
    #include <iostream.h>
    #include <fstream.h>
    
    struct HEADER {
     unsigned short bftype;
     unsigned int bfsize;
     unsigned short res1;
     unsigned short res2;
     unsigned int offset;
    };
    
    int main(void)
    {
     
     ifstream tester ("abitmap.bmp",ios::in|ios::binary);
    
     HEADER bmfh;
    
     tester.read((char *)&bmfh,sizeof(bmfh));
    
    ...
    Try this:

    tester.read((char*)&bmfh,sizeof(struct HEADER));

  4. #4
    elad
    Guest
    to quote J. Liberty (who isn't known to be God, but is a respected author nonetheless):

    If you use write(), you can recover the data using read().

    Therefore, I would say, if you didn't know how the files were written, you may not be able to read the struct all at once. Mr. Liberty also indicates that sizeof takes an object, not a class, as the argument. In addition, at least in his example, there are no parenthesis around the objects name. His syntax is:


    //Animal class defined here
    //two different objects of Animal class declared using different
    //constructors to assure initial values are different.
    Animal Bear(2, 500);
    Animal BearTwo;

    //declare streams using binary mode
    ofstream outputStream("filename", ios::binary);
    ifstream inputSream("filename", ios::binary);

    //write first object to file
    outputStream.write((char*) & Bear, sizeof Bear);

    //read data of first object back into second object
    inputStream.read((char* ) & BearTwo, sizeof Bear);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Input stream directly to structure elements?
    By thenrkst in forum C++ Programming
    Replies: 1
    Last Post: 04-24-2003, 11:43 AM