Hi,

I am a newbie to C++ and want to know how to parse thru a binary file. I am having some trouble with some simple code.

I have a sample binary file(test.bdb) that has "0069 0045 0089 0090" in the file.

Here is my code for the file.

ifstream infile;
infile.open("test.bdb", ios::in | ios::binary);
char* buffer = new char[4];
infile.read(buffer, 4);

I can't seem to read the binary file correctly. I just want to first be able to parse for "0069"(first entry of the binary file) butI don't see "0069" in buffer when I run the program. Can anyone tell me what I am doing wrong? Thanks.

Well as I see it only thing I would comment on is this :

infile.open("test.bdb", ios::in | ios::binary);

is not necessary because you have declared infile as ifstream pointer.
So this would be sufficient :

infile.open("test.bdb",ios::binary);

And ya apart from this I don't see any problem in the code frankly.But I would think it would be better if you checked the BDB file format and if your compiler has the bindings to read from such a file.

First: look at csurfer's post, second: look at this :)

BTW, Not related to the problem though: Do you deallocate the assigned memory as well (somewhere further in your code) ?

Correct me if I'm wrong but I don't think your actually intending to read the file as binary. Your file contains the "characters" 0069... So 0 would give you 48, 6 would give you 54, etc. according to ASCII. Try taking out the ios::binary flag.

Are those four different integers? Looks like a normal text file to me, not a binary file. If it were binary file then you wouldn't be able to read those integers. Try this:

int x;
infile.read( (char*)&x, sizeof(int));

or this

char* buffer = new char[4];
infile.read(buffer, 4);
int x = *(int *)buffer;

also this after removing ios::binary flag and reading as normal text file.

int x;
infile >> x;

@AncientDragon : I don't think the OP mentioned the need for reading the integers present in the file on the first hand.The problem he/she had was the reading of the character into buffer.So here I suppose the conversion to integer would be obsolete.

@nmaillet : Ya it is always read as ASCII values only as you said i,e 48 49 and all for 0 1 etc even when you open the file in normal text mode also because the values are stored in that way.But its the way in which we represent is important,when you read 00110000 into a char variable its nothing but character '0'.

Hi,

I am a newbie to C++ and want to know how to parse thru a binary file. I am having some trouble with some simple code.

I have a sample binary file(test.bdb) that has "0069 0045 0089 0090" in the file.

Here is my code for the file.

ifstream infile;
infile.open("test.bdb", ios::in | ios::binary);
char* buffer = new char[4];
infile.read(buffer, 4);

I can't seem to read the binary file correctly. I just want to first be able to parse for "0069"(first entry of the binary file) butI don't see "0069" in buffer when I run the program. Can anyone tell me what I am doing wrong? Thanks.

Does something like this produce your expected results?

#include <iostream>
#include <fstream>

int main()
{
   std::ifstream file("test.bdb", std::ios::binary);
   unsigned char low, high; /** Byte pair used to build an int. */
   while ( file.read((char*)&high, 1) && 
           file.read((char*)&low,  1) )
   {
      unsigned int value = high << 8 | low; /** Build the value. */
      std::cout << "value = 0x" << std::hex << value << "\n";
   }
   return 0;
}

/* my output
value = 0x69
value = 0x45
value = 0x89
value = 0x90
*/

Hi,

I tried all the above examples but for some reason do not get the right value. I should have stated that I am using a binary file and opened up the file in VIM and changed the file with the hex conversion function in VIM. So the "0069 0076 0048..." is really the hex representaion of the binary file. I attached the file(test.bin) and changed the extension to .cpp.

I keep getting "3030" as my first value. I have no idea why though. I implemented Dave Sinkula's way and keep seeing 3030 for "value". Arghh, can anyone tell me what is happening?

What I would like to do is that I have 10 binary files of equal lengths. I would like to read the first 16 bits of each binary file and compare with the the 1st 16 bits of every single file and see if there is any difference. Then I would like to read the next 16 bits and compare that with the 16 bits of all the other binary files and continue this on for the rest of the files. Still having problems with just parsing one binary file and getting the following output.

value = 0x69
value = 0x76
value = 0x48
value = 0x54
value = 0x92
......etc
Attachments
0000000: 0069 0076 0048 0054 0092 00ee 00c7 004a  .i.v.H.T.......J
0000010: 00ea 0009 00b2 004b 0034 00b9 000e 00a5  .......K.4......
0000020: 0019 00d5 0057 006f 0047 0095 00a4 0098  .....W.o.G......
0000030: 007f 004d 0062 007a 0022 00ca 0085 007a  ...M.b.z.".....z
0000040: 0d0a                                     ..

I attached the file(test.bin) and changed the extension to .cpp.

The file you attached appears not to be a binary file, but a text representation of some binary file. The "3030" stuff was text character as dicussed previously.

Try this attached file, but rename it as test.bdb. But really, if your source file is not an actual binary, then that is key to your issues.

ARgghh. Thank you Dave. Somehow my binary file seems not to be binary anymore. You are right. Maybe it got changed somehow when I kept modifying the extensions.

One question I had though is on this part of your code.

unsigned char low;
 file.read((char*)&low;

Just for my own knowledge, why not just declare the variable low as char, instead of typecasting the pointer to a character pointer?

Thanks a lot.

Just for my own knowledge, why not just declare the variable low as char, instead of typecasting the pointer to a character pointer?

When it comes to dealing with bytes, I prefer unsigned values. Signedness tends to bite me in the arse if I'm not watching.

#include <iostream>
#include <iomanip>
#include <fstream>

int main()
{
   std::ifstream file("test.bdb", std::ios::binary);
   char low, high; /** Byte pair used to build an int. */
   while ( file.read(&high, 1) && 
           file.read(&low,  1) )
   {
      unsigned int value = high << 8 | low; /** Build the int value. */
      std::cout << "value = 0x" 
                << std::setfill('0') << std::setw(4) 
                << std::hex << value << "\n";
   }
   return 0;
}

/* my output
value = 0x0069
value = 0x0045
value = 0xffffff89
value = 0xffffff90
*/
Comments
Solid posts :)
This article has been dead for over six months. Start a new discussion instead.