By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,332 Members | 1,404 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,332 IT Pros & Developers. It's quick & easy.

Trouble reading a binary file as float values

P: 15
Hi all,
I'm having a trouble reading a binary file as float values.I have to read the data in binary mode, then read every four bytes into a float variable. I have done my search, but i found out that the read and get functions do not accept float type. What should i do now? Can anybody help me please?

Here is the code..
Expand|Select|Wrap|Line Numbers
  1. #include <fstream>
  2.  
  3. #include <iostream>
  4.  
  5. using std::cout;
  6. using std::cin;
  7. using std::ios;
  8. using std::cerr;
  9. using std::endl;
  10. using std::fstream;
  11.  
  12.  
  13. void main()
  14. {
  15. fstream File("o1_o2.pwr1",ios::out | ios::in | ios::binary);
  16.  
  17. char value;
  18.  
  19. File.seekg(ios::beg); //go to the beginning of the file
  20.  
  21. File.get(value); //read one character
  22.  
  23. cout << value<< endl; //display it
  24.  
  25. File.close();
  26. }
Thank you all for your help :)
Mar 22 '07 #1
Share this Question
Share on Google+
31 Replies


Expert 100+
P: 1,510
you can use the read() function from fstream to read a sequence of bytes
http://www.cplusplus.com/reference/iostream/istream/read.html
Mar 22 '07 #2

P: 15
Thank you for your reply, but the problem is, the read function deals with char type, i need to read the data and tprint them into the screen as a float type :(
Mar 23 '07 #3

Expert 100+
P: 1,510
Thank you for your reply, but the problem is, the read function deals with char type, i need to read the data and tprint them into the screen as a float type :(
your can read/write any object by sepcifing the size (even an array), e.g. say you have a structure
Expand|Select|Wrap|Line Numbers
  1. struct  Test{          // test structure
  2.        int i;
  3.        float x;
  4.        };
  5.  
  6.  
  7. Test test;       // define a variable of type Test
  8.  fstream outfile;
  9.  
you can read and write test so
Expand|Select|Wrap|Line Numbers
  1.        outfile.read((char *) &test,sizeof(Test));
  2.        outfile.write ((char *) &test,sizeof(Test));
  3.  
note that you need to cast the address to a (char *)
have a look at binary files in
http://www.cplusplus.com/doc/tutorial/files.html
Mar 23 '07 #4

P: 15
What do u mean by "cast the address to a (char *)" ?
How can i do this?
Mar 23 '07 #5

Expert 100+
P: 1,510
What do u mean by "cast the address to a (char *)" ?
How can i do this?
the first parameter of the write() and read() functions is declared as char * - a pointer to char. So when you call them with a parameter which is not a char * you have to tell the compiler it is OK by casting - putting (char *) before the parameter as in
Expand|Select|Wrap|Line Numbers
  1.        outfile.read((char *) &test,sizeof(Test));
  2.        outfile.write ((char *) &test,sizeof(Test));
Mar 23 '07 #6

P: 15
the thing is, i need to output the data to the screen, but the data that comes out using these statements are "==" which has no meaning!! I modified my code to be like this:

Expand|Select|Wrap|Line Numbers
  1. ..
  2.  
  3. // read a file into memory
  4. #include <iostream>
  5. #include <fstream>
  6. using namespace std;
  7.  
  8. int main () {
  9.   int length;
  10.   char * buffer;
  11.  
  12.   //open the file
  13.   ifstream is;
  14.   is.open ("o1_o2.pwr1", ios::binary );
  15.   cout << "The file is opened.." << endl;
  16.  
  17.   // get length of file:
  18.   is.seekg (0, ios::end);
  19.   length = is.tellg();
  20.   is.seekg (0, ios::beg);
  21.   cout << "The file's length has been determined.." << endl;
  22.  
  23.   // allocate memory:
  24.   buffer = new char [length];
  25.   cout << "The memory is allocated.." << endl;
  26.  
  27.   // read data as a block:
  28.   is.read (buffer,length);
  29.  
  30.   is.close();
  31.   cout << "Reading data as a block.." << endl;
  32.  
  33.  
  34.   cout << "Writing data.." << endl;
  35.   cout.write (buffer,length);
  36.  
  37.   delete[] buffer;
  38.   return 0;
  39. }
  40.  
  41. ..

and i get outout like this:


قEذج╧Fd╟F♂EفYزEءQ3FcJmEاgdE┘≈G>ىF17hEَ7FX╨ F☻ؤF]P{E~h█F♦♣Eَ╩حF∟↨)F>@┬F>\Ex╤
(E╢صF♦╟E╪YٌFpفF░╫E═z Eد╫F MF►ه
F►QDF@═FCsإEdE┘╕F#♫F.k║F♠IEuHE\╜▀F☻↓7Eغ8pEٍO RFْ♣6Fb↨╜E╕╕_F*Z+FjإE┐▲'F(eيE
■/EWT}Eآ~XEْ♥F=→يEأ♫SEإ5E/qF <╔F@ُ:F!<←F#9╔Eى┘╖ENٍE╫Z╙E┼خ╒F☻P>EسZ#E╥آ[EdءْE

which is what i get when i open the file using Notepad, so i guess it need to be converted to a float type, but the thing is, how can i do this according to my code, knowing that the values i should get are float values?

Thank you for your help..and sorry for bothering you..
Mar 23 '07 #7

Expert 100+
P: 1,510
if the data has been written to the file as floating point values in binary it would appear as rubbish in notepad. You need to read it in as floats, e.g. make buffer
Expand|Select|Wrap|Line Numbers
  1.   float *buffer;
  2.  
and read it so
Expand|Select|Wrap|Line Numbers
  1.   // allocate memory:
  2.   buffer = new float [length/sizeof(float)];
  3.   cout << "The memory is allocated.." << endl;
  4.  
  5.   // read data as a block:
  6.   is.read ((char *)buffer, sizeof(float)*length);
  7.  
then try printing out the values in buffer and see if they make sense
Mar 23 '07 #8

P: 15
Now, my code looks like this:

Expand|Select|Wrap|Line Numbers
  1. // read a file into memory
  2. #include <iostream>
  3. #include <fstream>
  4. using namespace std;
  5.  
  6. int main () {
  7.   int length;
  8.   float * buffer;
  9.  
  10.   //open the file
  11.   ifstream is;
  12.   is.open ("o1_o2.pwr1", ios::binary );
  13.   cout << "The file is opened.." << endl;
  14.  
  15.   // get length of file:
  16.   is.seekg (0, ios::end);
  17.   length = is.tellg();
  18.   is.seekg (0, ios::beg);
  19.   cout << "The file's length has been determined.." << endl;
  20.  
  21.   // allocate memory:
  22.   buffer = new float [length];
  23.   cout << "The memory is allocated.." << endl;
  24.  
  25.   // read data as a block:
  26. //  is.read (buffer,length);
  27.   is.read ((char *)buffer, sizeof(float)*length);
  28.  
  29.   is.close();
  30.   cout << "Reading data as a block.." << endl;
  31.  
  32.  
  33.   cout << "Writing data.." << endl;
  34. //  cout.write (buffer,length);
  35.   cout.write ((char *)buffer, sizeof(float)*length);
  36.  
  37.   delete[] buffer;
  38.   return 0;
  39. }
  40.  
  41.  
and i got the same output !!
Mar 23 '07 #9

RedSon
Expert 5K+
P: 5,000
What part of "it will appear as rubbish in notepad" doesn't make sense? You can't look at binary float values in notepad because notepad does not read binary files. In fact you have to know what you are looking for in a binary file to even see what you are looking for.

The idea is to print out each floating point value while it is in the buffer.
Mar 23 '07 #10

P: 15
so, how can this be done?what is wrong with my code?
Mar 23 '07 #11

RedSon
Expert 5K+
P: 5,000
you can put a print statement right before or right after your buffer is read from or written to. Or you can just step through with a debugger and check to make sure the float value is correct.
Mar 23 '07 #12

P: 15
but the thing is, the output of the print statement is

قEذج╧Fd╟F♂EفYزEءQ3FcJmEاgdE┘≈G>ىF17hEَ7FX╨ F☻ؤF]P{E~h█F♦♣Eَ╩حF∟&#8616F>@┬F>\Ex╤
(E╢صF♦╟E╪YٌFpفF░╫E═z Eد╫F MF►ه
F►QDF@═FCsإEdE┘╕F#♫F.k║F♠IEuHE\╜▀F☻↓7Eغ8 pEٍO RFْ♣6Fb↨╜E╕╕_F*Z+FjإE┐▲'F(eيE
■/EWT}Eآ~XEْ♥F=→يEأ♫SEإ5E/qF <╔F@ُ:F!<←F#9╔Eى┘╖ENٍE╫Z╙E┼خ╒F☻P>EسZ#E╥آ[EdءْE

What do u think is the problem?
Mar 23 '07 #13

RedSon
Expert 5K+
P: 5,000
the problem is the print statement outputs ascii or unicode characters not floating point binary data. Get your self a program like TextPad and open it up in binary mode. Then you can see what your actual data looks like.
Mar 23 '07 #14

P: 15
Interesting..
I got numbers like this..

56E00: 44 3B 92 83 44 5A 6E EA 44 78 82 CF 44 32 E2 B7

what should i do now? Should i read the data in Hex mode?what should i change in my code?
Mar 23 '07 #15

P: 15
I forget to mention this..
56E00: 44 3B 92 83 44 5A 6E EA 44 78 82 CF 44 32 E2 B7 "some strange letters and signs here"
Mar 23 '07 #16

RedSon
Expert 5K+
P: 5,000
I forget to mention this..
56E00: 44 3B 92 83 44 5A 6E EA 44 78 82 CF 44 32 E2 B7 "some strange letters and signs here"
Good now you can see what your floating point numbers look like in Hex. Now in order to calculate your floating point numbers you can read this article which will help you understand how floating point numbers are encoded in binary.
Mar 23 '07 #17

P: 15
Well, its quite hard to understand, but there should be some conversion functions that i can use here, right? or i'll have to write a function to do this conversion?Plus, what would i have to convert?the Hex values or the strange signs and letters?
Mar 23 '07 #18

RedSon
Expert 5K+
P: 5,000
The strange signs and letters and the hex values are the same thing. You would probably benefit by reading this article.
Mar 24 '07 #19

RedSon
Expert 5K+
P: 5,000
Actually the conversion happens when you read in the binary data from the file stream. You tell the system to read from the file enough data to fill a float. The system reads in the amount of bits the system has defined as float and there you have it.
Mar 24 '07 #20

P: 15
So, the question is "How should i tell the system to read the data as float?" knowing that the read function does not deal with float type !!
Mar 24 '07 #21

Expert 100+
P: 1,510
So, the question is "How should i tell the system to read the data as float?" knowing that the read function does not deal with float type !!
have a look at this simple program which writes 10 float values to a file in binary mode and then reads them back
Expand|Select|Wrap|Line Numbers
  1. // write float to a binary file and read them back
  2. #include <fstream>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. int main () {
  7.   float test;
  8.   fstream outfile;
  9.   // create file with some data
  10.   outfile.open ("test.dat",  ios::binary | ios::out);
  11.     if (! outfile)                                                 // open OK ?
  12.         {
  13.         cout << "\nUnable to open file test.dat "  << strerror(errno);
  14.         cin.get();
  15.         return 1;                                                 // open failed
  16.         }
  17.   // write 10 floats to the file
  18.   for(int i=0; i< 10; i++)
  19.       {
  20.        test=i*1000.;
  21.        outfile.write ((char *) &test,sizeof(float));
  22.        }
  23.   outfile.close();  
  24.  
  25.   // now, open file for read/write
  26.   outfile.open ("test.dat",  ios::binary | ios::out | ios::in);
  27.   if (! outfile)                                                 // open OK ?
  28.         {
  29.         cout << "\nUnable to open file "  << strerror(errno);
  30.         return 1;                                                 // open failed
  31.         }
  32.   // print the contents 
  33.   cout << "\nfile contents\n";
  34.   while(outfile.good())
  35.       {
  36.        outfile.read((char *) &test,sizeof(float));
  37.        if(outfile.good()) cout << "test " << test << endl;
  38.        }
  39.    outfile.close();
  40.    system("pause");
  41.   return 0;
  42. }
  43.  
Mar 24 '07 #22

P: 15
Here is the code im working with now..

Expand|Select|Wrap|Line Numbers
  1.  
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <fstream>
  5.  
  6. using namespace std;
  7.  
  8. int main()
  9. {
  10.     ifstream infile;
  11.     char *inname = "o1_o2.pwr1";
  12.  
  13.     const int ByteNumber=8346836; 
  14.     int count=0;
  15.     unsigned i;
  16.     int length;
  17.     float x;
  18.     unsigned char *cXpoint = (unsigned char *)&x;
  19.  
  20.     infile.open(inname, ios::binary);
  21.     if (!infile) {
  22.         cout << "There was a problem opening file " << inname
  23.              << " for reading." << endl;
  24.         return 0;
  25.     }
  26.     cout << "Opened " << inname << " for reading." << endl;
  27.  
  28.     // get length of file:
  29.     infile.seekg (0, ios::end);
  30.     length = infile.tellg();
  31.     infile.seekg (0, ios::beg);
  32.     cout << "The file's length has been determined. \nLength = The number of bytes in the file = " << length << endl;
  33.  
  34.     int j = 0;
  35.  
  36.     infile.seekg (ByteNumber);
  37.  
  38. ///    while (!infile.eof())
  39. //    {
  40.         infile.read((char *)&x, sizeof(float));
  41.         if (!infile) {
  42.             cout << "There was a problem reading " << sizeof(float) << " bytes from " << inname << endl;
  43.             return 0;
  44.         }
  45.  
  46.         cout << "The sizeof(float) value is: " << sizeof(float) << endl;  
  47.         cout << "The value of x is: " << x << endl;
  48.         cout << "Successfully read a float from the file." << endl;
  49.         cout << "The count of word now is: " << count << endl; 
  50.         cout << "The bytes of x in memory : ";
  51.  
  52.         for (i = 0; i < sizeof(float); i++) 
  53.         {
  54.             cout << "0x" << hex << setfill('0') << setw(2) << (int)cXpoint[i] << " ";
  55.             count++;
  56.         }
  57.  
  58.         cout << endl;
  59.         cout << "x = " << fixed << setprecision(6) << x << endl << endl;
  60.  
  61. //    }
  62.  
  63.     return 0;
  64.  
  65. }
  66.  
  67.  
but the problem is, i have a float value that i should get as the value of a certain 4 byte, i get the right hexadecimal value for these 4 bytes as in the file i have (which i can access now using the TextPad). The value i am getting is 46 C3 74 BF which is not equal to the float value i should get, for these specific bytes, which is 1.359e+4
Can it be a conversion problem? If yes, how can i convert/read the hexadecimal value 46 C3 74 BF to get the float value 1.359e+4 ?

Thanks a lot for your help :)
Mar 24 '07 #23

Expert 100+
P: 1,510
what type of computer are you using ? on an intel 8086 family using IEEE 574 floating point representation 1.356e+4 would be 46545800 hexadecimal, see
http://www.h-schmidt.net/FloatApplet/IEEE754.html

If I run the following code
Expand|Select|Wrap|Line Numbers
  1. union data
  2. {
  3.      unsigned char ch[4];
  4.      float x;
  5. };
  6.  
  7. int main(void)
  8. {
  9.   data a;
  10.   a.x= 1.359e+4;
  11.   cout << a.x << endl;
  12.   for(int i=0; i<4;i++) cout << hex << (int)a.ch[i] << " ";
  13.  
on my PC using g++ I get
00 58 54 46
being a little endian machine
Mar 24 '07 #24

P: 15
I believe the file was created by a mac or linux OS, while im working now on a windows OS, would it make any difference?My program does produces the value 46 C3 74 BF by the float value -0.956105 but the problem, when i read these certain bytes using the program that has originally created the file im reading now, it displays the float value 1.359e+4 for the same Hex value !!
Mar 24 '07 #25

Expert 100+
P: 1,510
I believe the file was created by a mac or linux OS, while im working now on a windows OS, would it make any difference?My program does produces the value 46 C3 74 BF by the float value -0.956105 but the problem, when i read these certain bytes using the program that has originally created the file im reading now, it displays the float value 1.359e+4 for the same Hex value !!
x86 PC family are little endian and the power-pc Macs are big endian so this could be part of your problem. see
http://www.astro.gla.ac.uk/users/norman/star/sc13/sc13.htx/N-a2b3c2.html

however, this does not explain why the hex values are different
can you find out what the original machine that generated the file was?
Mar 25 '07 #26

Expert 100+
P: 1,510
what type of computer are you using ? on an intel 8086 family using IEEE 574 floating point representation 1.356e+4 would be 46545800 hexadecimal, see
http://www.h-schmidt.net/FloatApplet/IEEE754.html

If I run the following code
Expand|Select|Wrap|Line Numbers
  1. union data
  2. {
  3.      unsigned char ch[4];
  4.      float x;
  5. };
  6.  
  7. int main(void)
  8. {
  9.   data a;
  10.   a.x= 1.359e+4;
  11.   cout << a.x << endl;
  12.   for(int i=0; i<4;i++) cout << hex << (int)a.ch[i] << " ";
  13.  
on my PC using g++ I get
00 58 54 46
being a little endian machine
just ran this on an iMac (power PC) on got
46 54 58 00
confirms it is bit endian as against the little endian PC
Mar 25 '07 #27

P: 15
Help needed over here guys..Im totally convienced with the results i got, but looks like they are not the results expected by my Professor. I believe he is using other program to retrieve the data in float format. So, he said that the data i got is not the correct data. I dont know what to do now. The results im getting using my C++ program looks okay comparing with the values i get after converting the Hex values read by the TextPad Program from the data file im supposed to read. All he said was, you have to read the data file in binary mode, then read each four bytes into a float variable, and this is what i have done; yet, i cannot get the correct results. What might be the problem..Please Help :(
Mar 26 '07 #28

RedSon
Expert 5K+
P: 5,000
It sounds like you are going to have to discuss with your professor the point of the project. If there is some particular aspect of programming that you are supposed to learn by doing this assignment then you have to ask your professor to decide if you have in fact learned that or not. If the point of the lesson is to write some code that manipulates some binary data, ask your professor if you have not demonstrated that you can do that.
Mar 26 '07 #29

RedSon
Expert 5K+
P: 5,000
The point is that there are any number of ways to solve a problem in programming, you can do things a million different ways. Just because you solved a problem differently then what your professor expects to see does not mean that you should be penalized. If however you did not follow some of the project rules then it is your own fault.
Mar 26 '07 #30

P: 15
Anyhow, the float value for a Hex value will never change, it can either be read in a big-endian or little-endian format, right?How can i get some third float value for the same Hex value?It doesnt even sound logical !!
Mar 26 '07 #31

Expert 100+
P: 1,510
Anyhow, the float value for a Hex value will never change, it can either be read in a big-endian or little-endian format, right?How can i get some third float value for the same Hex value?It doesnt even sound logical !!
The machine used to create the file may not have used floating point format IEEE754 - can you find out details of the machine? model, operating system, compiler, etc
Mar 27 '07 #32

Post your reply

Sign in to post your reply or Sign up for a free account.