Read binary file and transfer to human readable text file

Hi, I had a problem to transfer a binary file to normal text file. I stored 24000 float number in the binary file, so the size of this binary file is eaxct 96000 bytes. I wanna read all these numbers and store them in a text file(6 numbers on each line). I'm a newbie on the fstream class. Here is the test codes. Any suggestion is welcome.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <cstdio>
#include <cmath>
#include <fstream>
#include <iostream>
#include <cstdlib>

using namespace std;

void read_from_binary_file()
{
	char *buffer;

	ifstream infile("binary.000010000",ios::binary);
	if(!infile.is_open())
	{
		printf("The input file was opened fail!");
		exit(1);
	}

	ofstream outfile("text.000010000");
	if(!outfile.is_open())
	{
		printf("The output file was opened fail!");
		exit(1);
	}
	else
	{
		outfile.setf(ios::fixed);
		outfile.setf(ios::showpoint);
		outfile.width(12);
	}

	buffer = new char[sizeof(float)];

	for(int i=0;i<4000;i++)
	{
		for(int j=0;j<6;j++)
		{
			infile.read(buffer,sizeof(float));
			outfile.write(buffer,sizeof(float));
		}

		outfile<<endl;
	}

	delete [] buffer;

	infile.close();
	outfile.close();
}

int main()
{
	read_from_binary_file();
	return 1;
}
Line 33: just make an array of six floats, and reinterpret_cast<> them to char pointers.

Line 39: now you can move this outside the inner loop, and read six floats at a time...

Line 40: this just writes the binary data back out... but you want a text output. Use the insertion operator (<<).

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <fstream>
#include <iomanip>
#include <iostream>
using namespace std;

void make_floats()
  {
  ofstream f( "floats.bin", ios::binary );
  float a = 0.0f;
  for (unsigned n = 0; n < 15; n++)
    {
    f.write( reinterpret_cast <char*> (&a), sizeof( float ) );
    a = a + 1.1;
    }
  }

bool bin_to_text( istream& ins, ostream& outs )
  {
  float    floats[ 6 ];
  unsigned gcount;
  unsigned count;

  while (true)
    {
    // Read the binary data: six floats
    ins.read( reinterpret_cast <char*> (&floats), sizeof( floats ) );
    gcount = ins.gcount();
    count = gcount / sizeof( float );

    // Verify some data was read, and that all data were read in whole
    if (!count) break;
    if ((count * sizeof( float )) != gcount) return false;

    // Write six floats to a line
    for (unsigned n = 0; n < count; n++)
      outs << setw( 12 ) << floats[ n ] << " ";
    outs << endl;
    }

  return true;
  }

int main()
  {
  make_floats();

  ifstream inf( "floats.bin", ios::binary );
  ofstream outf( "floats.txt" );
  outf.setf( ios::fixed );
  outf.setf( ios::showpoint );
  bin_to_text( inf, outf );
  return 0;
  }

Hope this helps.
@Duoas
Thanks for your reply,but i still get a few puzzles.

line 13: why a=a+1.1 , isn't a++ ok ?
line 26-28: the comments are my understandings
1
2
3
ins.read( reinterpret_cast <char*> (&floats), sizeof( floats ) );  //try to read whole six floats
    gcount = ins.gcount();                     //get the actual read characters,i.e. bytes read
    count = gcount / sizeof( float );   //calculate the actual floats read 


Am i right ? If I am,then i just can not figure out what is line 32 for.
if ((count * sizeof( float )) != gcount) return false;
Isn't this if condition guaranteed to be true,cause variable count is calulated via division,and you just perform the reversed operation?

Please help me。
Thanks in advance!
Sure, if you only want to increment by one... it is just an example, after all, and I wanted to see some digits after the decimal point.

Your understandings are correct.

Line 32 checks that you managed to read an entire float... if your file is only 10 bytes long then there is something wrong.

This example was really just typed-in and tested in a few minutes.. don't read anything too profound from it. In retrospect, I probably should have put line 32 after line 37.

Glad to have been helpful.
Gotcha
@Duoas
Thanks for your reply. I tried your method. The codes works now. Instead of declare floats[6], I use "new" to allocate memory for variable "floats". But it doesn't work. After line 27
 
gcount = ins.gcount();

gcount = 4(not 24). What's the difference between these two methods? Thanks.
@Duoas
Another quick question, in line 26
 
ins.read( reinterpret_cast <char*> (&floats), sizeof( floats ) );

I think "floats" is already a pointer of "float[6]", why do we need to put another "&" in front of it? Thanks
The gcount() returns the number of bytes read from the last input operation.
I used a trick to get the size of the array:
1
2
float floats[ 6 ];
// sizeof( floats ) == sizeof( array ) == 6 floats * 4 bytes for a float == 24 
1
2
float* floats = new float[ 6 ];
// sizeof( floats ) == sizeof( pointer ) == 4 bytes for a pointer == 4 
The type of a thing makes a big difference.

Line 26: I don't know... I just put it there by accidental habit... it isn't really necessary. (But it doesn't hurt in this case.)
@Duoas
Thanks a lot. Really help me a lot.
Topic archived. No new replies allowed.