Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Binary File I/O problem

Posted on 1998-12-16
Last Modified: 2013-11-15
I am reading a binary file (a windows bmp) and what I get when I do myin>>data and what I see when I do a HEX dump of the file are completely different.  What am I doing wrong?

Here's my code:

{fstream myin(filename,ios::in/* | ios::binary*/);
BitmapFileHeader File;
BitmapInfo Info;
RGBQuad* Colors;
BYTE* BitmapBits;
//read file header

where bfType, bfReserved1, and bfReserved2 are declared as unsigned short (2 bytes for my compiler) and the others are declared as unsigned int (4 bytes for my compiler)

The first 14 bytes of the file (the struct that I am trying to read in above) as seen by a HEX dump program are:

42 4D 08 53 00 00 00 00 00 00 36 00 00 00

but when I read in the data, put a watch on it, and look at the memory dump in hex (which should be the same) I get

8C 3A
60 81 00 00
57 00
00 00
00 00 20 3E

I have never done anything with binary files before this, so I think I am not reading it in correctly.

I am using Borland C++ 5.0

Can anyone help me?  Any suggestions are welcome...
Question by:ris
  • 7
  • 6
  • 2
  • +2
LVL 22

Expert Comment

ID: 1180318
I see that the ios:binary is commented out.  Why?  that is necessary for what you are doing.

Author Comment

ID: 1180319
I commented it out as part of my experimentation to get the code to work.

Uncommenting it out changed my results, but it still doesn't work.  Now the first two bytes are 00 4F.

The rest are different, too, but not in any kind of pattern than I can tell.

Author Comment

ID: 1180320
I'm starting to suspect that my compiler does not handle binary files.

I wrote this code just to simplify my problem a little bit and to play with binary files in general

  fstream myio("test.ris",ios::out|ios::binary);
  int a=10;
  int b=20;

What happens is that the CHARACTERS 1020 are written to the file (as they would be if it were non-binary) and then when I read them back in, it reads it as an ascii file and reads the number 1020 into b and stops because it reaches eof, so the cout on the last line prints


So obviously, either my compiler doesn't implement binary files for some reason (I doubt it) or I have done something wrong, but according to my documentation, I have done everything correctly.

What am I missing?
Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.


Author Comment

ID: 1180321
I'm increasing the points because it is really important to me to get this working in the next 2 days
LVL 22

Expert Comment

ID: 1180322
>>I'm starting to suspect that my compiler does not handle binary files
I'm sure that is not the case.

Is that ALL the code you have involving that file or that stream object?  i.e is it possible tha the file is getting written over by something else?
LVL 12

Expert Comment

ID: 1180323
I think the problem is that the behaviour of the << operator is to output the number as a string to the file. The fact the file is binary does not necessarily matter. I think you need to override the << operator (or find the stream class that implements it in the way you want it.


LVL 22

Expert Comment

ID: 1180324
<< outputs in the current mode.

ris, if you could post your entire program or mail it to nietod@theshop.net.  I might be able to see something.

Expert Comment

ID: 1180325
I'm sorry, 'cause there's not much time (not only for you, but for me, know!)
I didn't have time to verify it, but I think the problem is reading 2 x 2 Bytes into
a long. Think about this:
You have two Bytes:
Hex. A -> 1011 binary
Hex. B -> 1100 binary

Concated: Hex. AB, but binary concated 10111100 is Hex. D0. (Don't know if I
"computed" right!).
So, try to read Byte by Byte, perhaps by using pure C-Code fread(..) function.
So long ...
LVL 22

Expert Comment

ID: 1180326
You can read and write multi-byte quantities with a binary stream with no problem.

Author Comment

ID: 1180327
I have noticed that if I read in a char (1 byte at a time) it works correctly.  However, that is the case in ascii mode as well as binary, so it supports my theory that my file is not being openned in binary mode for some reason.

My "test-the-binary-mode" program above (the one from Wednesday, December 16 1998 - 07:16PM PST) is the whole program that I wrote just for the purpose of playing with binary files (which, as stated above, didn't work)  There is no way that that file (test.ris) was being touched by anything else at the time.

nietod: I'll mail you my code in a couple minutes.

Author Comment

ID: 1180328
ok, now I know it's not me.  I tried CC under unix on my school account and I still get
for the output of my test program.
LVL 10

Expert Comment

ID: 1180329
That output is correct

<< is writing the number as a string of characters "1" "0" "2" "0" so when you read in b it reads in the string "1020" and converts it to an int (note you are reading the variables in opposite order to the way you wrote them and a stil has value 10 because it doesnt get changed (b read in all the data).

Don't use << or >> for binary io ... try 'write' instead


Author Comment

ID: 1180330
Actually nietod already answered my question through an email discussion with me and I promised him the points.

We came to the same conclusion: that the << and >> operators always write in ascii mode.  So the only way is to use the read and write operators, which operate on character strings, which essentially means that binary mode is a meaningless thing.

On the good side though, it is possible to do a nice thing like this:

typedef struct {
int x
int y
char z
short a
} mystruct;

char* temp;
mytemp x;

and the whole struct is read in all at once.  The write can be done similarly.

To reiterate, I promised the points to nietod, so please do not answer the question unless you are him.
LVL 22

Accepted Solution

nietod earned 200 total points
ID: 1180331
Thanks, but to clarify two points:  

read() and write() only work on char  for fstream's not for basic_fstream, which can work with any type.

Binary mode is not meaningless--but close to it.  It prevents special interpretation of the newline, carriage return, and line feed characters.  It has no effect during a read() or write() operation.

Expert Comment

ID: 1180332
Once again:
Did you test it until know?!?
I mean reading 2 Bytes to int ?!?

Author Comment

ID: 1180333
Yes, I tested reading to bytes into an int (or 4 in the case of my compiler's implementation of int) and I also tested the structure read that I described earlier and both work, at least with Borland C++ compiler...

CC on Unix complains with an error like "bad assignment char* = mystruct*"
LVL 22

Expert Comment

ID: 1180334
It will work on other compilers as well.  That is how the STL designers intend for programs to do binary I/O.  An unfortunate choice, I think.   They could have made the << and >> operations do binary I/O as well as ASCII.

The error you are getting on CC suggests that you forgot to cast the pointer passed to read() or write() to a char * pointer.  it should have been like

MyFile.read( (char *) &mystruct, sizeof(mystruct) );

Featured Post

Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
PCAnywhere 2 134
Determining Project Cost 1 84
Issue with using GPO to install Mimecast in Outlook. 6 50
WinX Downloader fails to analyze. 10 55
Workplace bullying has increased with the use of email and social media. Retain evidence of this with email archiving to protect your employees.
All of the resources available today make learning a new digital media easier than ever-- if you know where to begin. This is a clear, simple guide to a few of the basic digital art mediums and how to begin learning them on your own.
The viewer will learn how to successfully download and install the SARDU utility on Windows 8, without downloading adware.
An overview on how to enroll an hourly employee into the employee database and how to give them access into the clock in terminal.

791 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question