Can someone explain, how can read a binary file. I'm really nervous with this.

I wrote one as follows.

string line;
	ifstream fileread ("[I]path to the binary file[/I]");

	while(! fileread.eof())
	{
		getline(fileread, line);
		cout << line << endl;
	}

	fileread.close();

Well I read a binary file using this, the command prompt is really mad. It,s not displays as a binary code, I mean bunch of zeros and ones.

Can you say where I'm going wrong.

Of course it won't. You could see all scraps. Binary files are not the one which are written as 01010101011110. It means that the data is encoded as binary.

I wrote one as follows.

string line;
	ifstream fileread ("[I]path to the binary file[/I]");

	while(! fileread.eof())
	{
		getline(fileread, line);
		cout << line << endl;
	}

	fileread.close();

Well I read a binary file using this, the command prompt is really mad. It,s not displays as a binary code, I mean bunch of zeros and ones.

Can you say where I'm going wrong.

Two problems:
1: Binary data is not string data. You should probably be using a char array.
2: while(! fileread.eof()) will not work properly. See this ( feof() is the same as .eof() )

1: Binary data is not string data. You should probably be using a char array.

How does that make a difference? A string just handles the memory for the char array instead of making you do it. I don't think there should be any problem with using a string as long as you don't do any text conversions.

ifstream fileread ("path to the binary file");
string contents;
char ch;

// Get the binary data
while ( fileread.get( ch ) ) {
  contents.push_back( ch );
}

// Print the binary data as hex
for ( int i = 0; i < contents.size(); ++i ) {
  cout<< hex << int( contents[i] ) <<" ";
}

fileread.close();

why not just do it the quick and easy way, assuming the binary file is no larger than the char buffer. If the size is unknown than we'd have to first find out the file size and allocate the buffer appropriately. In any case it will be a lot faster then reading the fine one byte at a time.

Also, make sure to open the file in binary mode, not the default text mode.

unsigned char iobuf[1024];

fileread.read(iobuf,sizeof(iobuf));

Aother problem with using std::string like that is that std::string can not be typecast into a structure like character buffers can. The contents of the binary file may well be a structure and reading it into a std::string would destroy that.

why not just do it the quick and easy way

Because the quick and easy way is usually more costly in the long run? :D

In any case it will be a lot faster then reading the fine one byte at a time.

You don't have to read it one byte at a time if that's what you're worried about.

// Get the binary data
char iobuf[1024];

while ( fileread.read( iobuf, sizeof( iobuf ) ) {
  contents += iobuf;
}

Now you don't have to worry about buffer sizes, or find the size of the file, or worry about allocating and freeing memory. :)

Aother problem with using std::string like that is that std::string can not be typecast into a structure like character buffers can. The contents of the binary file may well be a structure and reading it into a std::string would destroy that.

Why can't you do it? A string has the data() method, and I don't understand why (somestruct)iobuf is any different from (somestruct)contents.data() if they both have the same characters.

>> .. really mad. It,s not displays as a binary code, I mean bunch of zeros and ones.

if all you want to do is display the contents of a file as a sequence of bits (i presume that is what you mean by bunch of zeros and ones),

#include <fstream>
#include <limits>
#include <bitset>
#include <iostream>
using namespace std;

int main()
{
  ifstream file( __FILE__ ) ; file >> noskipws ;
  typedef bitset< numeric_limits<unsigned char>::digits > bitset ;
  unsigned char byte ;
  while( file >> byte ) cout << bitset(byte) ;
}

Because the quick and easy way is usually more costly in the long run? :D

How's that? can you show an example?

You don't have to read it one byte at a time if that's what you're worried about.

// Get the binary data
char iobuf[1024];

while ( fileread.read( iobuf, sizeof( iobuf ) ) {
  contents += iobuf;
}

I don't think std::string class will work with binary data like that. I think the += operator will stop when it encounters the first 0 byte in the iobuf.


Why can't you do it? A string has the data() method, and I don't understand why (somestruct)iobuf is any different from (somestruct)contents.data() if they both have the same characters.

I don't see a difference either (1) if it works (see above comment) and (2) except that old farts like me just perfer using char arrays when the problem suits it better :)

How's that? can you show an example?

I can't, but my teachers like to say that if you don't do something right the first time, you end up doing it again and again to fix the problems. It seems to me that using an array is bad because you lock yourself into a buffer size, and using allocated memory is bad because you have to work harder to make it work right and keep it working. The C++ string fixes both of those because it grows on its own and you don't have to manage it.

I don't think std::string class will work with binary data like that. I think the += operator will stop when it encounters the first 0 byte in the iobuf.

Yeah, I tried it. But assign and append let you pick a count for the incoming string. This works. :)

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

using namespace std;

#define SETUP 1

int main() {
  string contents;

#ifdef SETUP
  ofstream binaryOut( "binary.dat", ios::binary );

  contents.assign( "C code.\0C code run.\0Run code run.", 33 );
  binaryOut.write( contents.data(), contents.size() );

  binaryOut.close();
#else
  ifstream binaryIn( "binary.dat", ios::binary );

  // Get the binary data
  char iobuf[1024];

  do {
    binaryIn.read( iobuf, sizeof( iobuf ) );
    contents.append( iobuf, binaryIn.gcount() );
  } while ( binaryIn );

  binaryIn.close();

  // Print the characters
  for ( int i = 0; i < contents.size(); ++i ) {
    if ( !isprint( contents[i] ) ) {
      cout<< int( contents[i] );
    } else {
      cout<< contents[i];
    }
  }

  cout<<"\n";
#endif

  return 0;
}

and (2) except that old farts like me just perfer using char arrays when the problem suits it better

But does the problem really suit char arrays better or are the old farts just doing what they're comfortable with? ;) If the file is always a fixed size that's great, but if it's not you have to make a super huge char array to accommodate the expected sizes and add extra logic in case the size is bigger than the array. If you don't want to wrestle with that, you have to dynamically allocate a char array, and that's just a lot of memory management that you don't need to do. It makes the code longer and harder to keep up.

Comments
Good example of how to make std::string work with binary files

>>I can't, but my teachers like to say that if you don't do something right the first time, you end up doing it again and again to fix the problems
And your teachers are right. Sofware companies spend probably three times (or more) the money in program maintenance then in original development.

One thing that the OP could clarify is whether or not it is necessary to read the whole file into memory, or whether it might simply be simpler and easier to process as a stream.

How does that make a difference? A string just handles the memory for the char array instead of making you do it. I don't think there should be any problem with using a string as long as you don't do any text conversions.

ifstream fileread ("path to the binary file");
string contents;
char ch;

// Get the binary data
while ( fileread.get( ch ) ) {
  contents.push_back( ch );
}

// Print the binary data as hex
for ( int i = 0; i < contents.size(); ++i ) {
  cout<< hex << int( contents[i] ) <<" ";
}

fileread.close();

Actually later I want to convert some parts to decimal.

>> .. really mad. It,s not displays as a binary code, I mean bunch of zeros and ones.

if all you want to do is display the contents of a file as a sequence of bits (i presume that is what you mean by bunch of zeros and ones),

#include <fstream>
#include <limits>
#include <bitset>
#include <iostream>
using namespace std;

int main()
{
  ifstream file( __FILE__ ) ; file >> noskipws ;
  typedef bitset< numeric_limits<unsigned char>::digits > bitset ;
  unsigned char byte ;
  while( file >> byte ) cout << bitset(byte) ;
}

Great, Thanks.

But I need one thing to do there. I want to count the number of bits. I'll try it now. Do you have any suggestions.

Do you need to read in your file as binary, or is it just a plain text file?

There what I want. I don't think that repeating it.

I have a binary file and,

1.) read the file as binary (zeros and ones)

2.) count the number of bits

3.) group them, including in predefined number of bits. Say in my file have 1000bits, and I want to group them of 10bits. Simply divide by 10 of 1000.

4.) display some of the groups in a separate text file. Some of them as it is and some of them as decimal.

Actually that binary file is a message which are store in our university server. I want read it, then collect some informations. That's the basic idea.

I think clear enough me to all of you.

I'm not sure that I have use the correct word for my requirement. Here the issue.

Read a binary file and count the number of bits using following way.

ifstream :: pos_type size ;
char * memblock ;

int main()
{
	ifstream fileread ("RecordBinaryData.txt", ios::in|ios::binary|ios::ate) ;
	if(fileread.is_open())
	{
		size = fileread.tellg () ;
		memblock = new char [size] ;
		fileread.seekg (0, ios :: beg) ;
		fileread.read (memblock, size) ;
		fileread.close () ;

		cout << "\nSize of the file is " << (size * 8) << " bits." ;

		delete[] memblock;
	}
}

Is this correct?

Next I want to store them to an array. So the length should be (size*8), in bits. I tried,

long arr[(size * 8)]

and failed. Why is that?

Why not read a byte at a time and multiply the result by CHAR_BIT or equivalent?

Can you explain little more. I'm really newbie for those stuff. Help appreciate.

Open a file in binary mode. Read a byte, increment a counter. When you're done reading the file, multiply the resulting counter by the number of bits in a byte.

I think clear enough me to all of you.

Yeah, but I think you have enough info and code from everyone in this thread to help you write more of your program. It's starting to seem like you're asking us to write it for you.

Yeah, but I think you have enough info and code from everyone in this thread to help you write more of your program. It's starting to seem like you're asking us to write it for you.

No sir, after reading a lots of tutorials on the web and discussions in this forum I'm really confusing. As I said earlier, I'm new for C++ and my basic knowledge also in lower level.

The number of bits in the file is the number of bytes in the file multiplied by the number of bits in a byte.

Ya it's true. What the point here.

Anyway now I know that how many bytes are there. Actually I count them. But now I have another question here. I want to store that number in an array.

So, after counting number of bytes there, equal it to the constant value and put it to the array. But get the error.

error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'block' : unknown size

This is code,

long count = 0 ;

	if(filebin.is_open())
	{
		while( file >> byte )
		{
			filebin << bitset(byte) ;
			count++ ;
		}
		filebin.close() ;

		const long const_count = count ;
		long arr[const_count];
	}

What's wrong there.

This article has been dead for over six months. Start a new discussion instead.