Thread: Trouble reading a binary file as float values - I need the EXPERTs' HELP in C++ code!

  1. #1
    Registered User
    Join Date
    Mar 2007
    Posts
    4

    Trouble reading a binary file as float values - I need the EXPERTs' HELP in C++ code!

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


    Code:
    // read a file into memory
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main () {
      int length;
      float * buffer;
    
      //open the file
      ifstream is;
      is.open ("o1_o2.pwr1", ios::binary );
      cout << "The file is opened.." << endl;
    
      // get length of file:
      is.seekg (0, ios::end);
      length = is.tellg();
      is.seekg (0, ios::beg);
      cout << "The file's length has been determined.." << endl;
    
      // allocate memory:
      buffer = new float [length];
      cout << "The memory is allocated.." << endl;
    
      // read data as a block:
    //  is.read (buffer,length);
      is.read ((char *)buffer, sizeof(float)*length);
      
      is.close();
      cout << "Reading data as a block.." << endl;
    
      
      cout << "Writing data.." << endl;
    //  cout.write (buffer,length);
      cout.write ((char *)buffer, sizeof(float)*length);
    
      delete[] buffer;
      return 0;
    }

    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∟&#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

    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, when i opened the file in Binary mode using TextPad, i got numbers like this:

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

    The thing is, how can i do this according to my code, knowing that the values i should get are float values?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    A couple of points.
    1. You need to divide the length of the file by sizeof(float) to get the number of floats in the file.
    length = is.tellg() / sizeof(float);

    2. When you print stuff, do something like
    for ( int i = 0 ; i < length ; i++ ) cout << buffer[i] << endl;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2007
    Posts
    4
    Here is the code im working with now..

    Code:
     
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        ifstream infile;
        char *inname = "o1_o2.pwr1";
    
    	const int ByteNumber=8346836; 
    	int count=0;
        unsigned i;
        int length;
    	float x;
        unsigned char *cXpoint = (unsigned char *)&x;
    
        infile.open(inname, ios::binary);
        if (!infile) {
            cout << "There was a problem opening file " << inname
                 << " for reading." << endl;
            return 0;
        }
        cout << "Opened " << inname << " for reading." << endl;
    
    	// get length of file:
        infile.seekg (0, ios::end);
        length = infile.tellg();
        infile.seekg (0, ios::beg);
        cout << "The file's length has been determined. \nLength = The number of bytes in the file = " << length << endl;
    
    	int j = 0;
    
        infile.seekg (ByteNumber);
    
    ///	while (!infile.eof())
    //	{
    		infile.read((char *)&x, sizeof(float));
    		if (!infile) {
    			cout << "There was a problem reading " << sizeof(float) << " bytes from " << inname << endl;
    			return 0;
    		}
    
    		cout << "The sizeof(float) value is: " << sizeof(float) << endl;  
    		cout << "The value of x is: " << x << endl;
    		cout << "Successfully read a float from the file." << endl;
    		cout << "The count of word now is: " << count << endl; 
    		cout << "The bytes of x in memory : ";
    
    		for (i = 0; i < sizeof(float); i++) 
    		{
    			cout << "0x" << hex << setfill('0') << setw(2) << (int)cXpoint[i] << " ";
    			count++;
    		}
    	    
    		cout << endl;
    		cout << "x = " << fixed << setprecision(6) << x << endl << endl;
    
    //	}
    
        return 0;
    
    }
    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

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Code:
    #include <stdio.h>
    
    int main(void) {
      union {
        float a;
        unsigned char b[4];
      } u;
      printf("%u %u %u\n", sizeof(u), sizeof(u.a), sizeof(u.b) );
      u.b[0] = 0x46;
      u.b[1] = 0xc3;
      u.b[2] = 0x74;
      u.b[3] = 0xbf;
      printf("%f\n", u.a );
      u.b[3] = 0x46;
      u.b[2] = 0xc3;
      u.b[1] = 0x74;
      u.b[0] = 0xbf;
      printf("%f\n", u.a );
      u.a = 1.359e+4;
      printf("%f = %02x %02x %02x %02x\n",
        u.a, u.b[0], u.b[1], u.b[2], u.b[3] );
      return 0;
    }
    It could be an endian problem - the bytes are reversed on your machine compared to the machine which wrote the file.

    But on an x86 with IEEE format floats, your hex values don't correspond to that float value.
    $ ./a.exe
    4 4 4
    -0.956105
    25018.373047
    13590.000000 = 00 58 54 46
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Mar 2007
    Posts
    4
    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 !!

  6. #6
    Registered User Noir's Avatar
    Join Date
    Mar 2007
    Posts
    218
    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?
    Yeah, that makes a huge difference.Binary files aren't portable, so you're stuck unless you can decipher the format and read it the way it was written.

  7. #7
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Think about the code that you were just given and study the output. Notice how the hexadecimal output is different? Notice how it's in reverse?

    http://en.wikipedia.org/wiki/Endianess

    This means if you have a hexadecimal 32-bit number of 0x01020304 in memory, on a system with a big-endian memory layout, it'll be put as follows in memory:

    Code:
    01 02 03 04
    On a system that use the little-endian convention (ie. Windows on Intel), it'll be saved "backwards". You'll get the following:

    Code:
    04 03 02 01
    It's something you need to live with and learn.

    Make sure you know what you're reading, what order you want to get it, and the rest.

  8. #8
    Registered User
    Join Date
    Mar 2007
    Posts
    4

    Unhappy

    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

  9. #9
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Well if he's testing it on a big endian machine, and the file is in big endian, write it as if everything is in the correct order and ignore endianess for now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie homework help
    By fossage in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 04:27 PM
  2. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  3. Reading in a binary file from offset into another file
    By cloudy in forum C++ Programming
    Replies: 5
    Last Post: 05-24-2006, 03:01 AM
  4. multiple file loading. so fruturated! help!
    By psychopath in forum Game Programming
    Replies: 5
    Last Post: 05-09-2005, 05:13 PM