Search code examples
c++filebinaryhexfilestream

writing to a binary file in c++


My problem is that I have a string in hex representation say: 036e. I want to write it to a binary file in the same hex representation. I first converted the string to an integer using sstrtoul() function. Then I use fwrite() function to write that to a file. Here is the code that I wrote. I get the following output in my file after running this:

6e03 0000

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

using namespace std;

int main() {
  ofstream fileofs("binary.bin", ios::binary | ios::out);
  string s = "036e";
  int x = strtoul(s.c_str(), NULL, 16);
  fileofs.write((char*)&x, sizeof(int));
  fileofs.close();
}

While the result that I expect is something like this:

036e

Can anybody explain exactly what I'm doing wrong over here?


Solution

  • Your problem has to do with endianees and also with the size of an integer.

    For the inverting bytes the explanation is that you are running in a little-endian system.

    For the extra 2 zeros the explanation is that you are using a 32 bit compiler where ints have 4 bytes.

    There is nothing wrong with your code as long as you are going to use it always in 32 bit, little-endian systems.

    Provided that you keep the system, if you read your integers from the file using similar code you'll get the right values (your first read integer will be 0x36E).

    To write the data as you wish you could use exactly the same code with minor changes as noted bellow:

    unsigned short x = htons(strtoul(s.c_str(), NULL, 16));
    fileofs.write((char*)&x, sizeof(x));
    

    But you must be aware that when you read back the data you must convert it to the right format using ntohs(). If you write your code this way it will work in any compiler and system as the network order is allways the same and the converting functions will only perform data changes if necessary.

    You can find more information on another thread here and in the linux.com man page for those functions.