954,500 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Dynamic array

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

eranga262154
Junior Poster
185 posts since Sep 2007
Reputation Points: 32
Solved Threads: 2
 
vishesh
Nearly a Posting Virtuoso
1,381 posts since Oct 2006
Reputation Points: 85
Solved Threads: 42
 

I wrote one as follows.

string line;
	ifstream fileread ("<em>path to the binary file</em>");

	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.

eranga262154
Junior Poster
185 posts since Sep 2007
Reputation Points: 32
Solved Threads: 2
 

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.

vishesh
Nearly a Posting Virtuoso
1,381 posts since Oct 2006
Reputation Points: 85
Solved Threads: 42
 

So, what should I do? Can you explain a little more.

eranga262154
Junior Poster
185 posts since Sep 2007
Reputation Points: 32
Solved Threads: 2
 
So, what should I do? Can you explain a little more.

What do you want to do? Read More .

vishesh
Nearly a Posting Virtuoso
1,381 posts since Oct 2006
Reputation Points: 85
Solved Threads: 42
 
galin
Newbie Poster
10 posts since Aug 2007
Reputation Points: 10
Solved Threads: 2
 

Thanks for all the links.

eranga262154
Junior Poster
185 posts since Sep 2007
Reputation Points: 32
Solved Threads: 2
 

I wrote one as follows.

string line;
	ifstream fileread ("<em>path to the binary file</em>");

	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 notstring 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() )

WaltP
Posting Sage w/ dash of thyme
Moderator
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 
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();
Hamrick
Posting Whiz
325 posts since Jun 2007
Reputation Points: 180
Solved Threads: 34
 

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.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

>> .. 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) ;
}
vijayan121
Posting Virtuoso
1,606 posts since Dec 2006
Reputation Points: 1,159
Solved Threads: 287
 
why not just do it the quick and easy way


Because the quick and easy way is usually more costly in the long run? :DIn 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.

Hamrick
Posting Whiz
325 posts since Jun 2007
Reputation Points: 180
Solved Threads: 34
 

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

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 
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 :)

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 
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.

Hamrick
Posting Whiz
325 posts since Jun 2007
Reputation Points: 180
Solved Threads: 34
 

>>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.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

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.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

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.

eranga262154
Junior Poster
185 posts since Sep 2007
Reputation Points: 32
Solved Threads: 2
 

>> .. 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.

eranga262154
Junior Poster
185 posts since Sep 2007
Reputation Points: 32
Solved Threads: 2
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You