Take the 2-minute tour ×

I've written several ints, char[]s and the such to a data file with BinaryWriter in C#. Reading the file back in (in C#) with BinaryReader, I can recreate all of the pieces of the file perfectly.

However, attempting to read them back in with C++ yields some scary results. I was using fstream to attempt to read back the data and the data was not reading in correctly. In C++, I set up an fstream with ios::in|ios::binary|ios::ate and used seekg to target my location. I then read the next four bytes, which were written as the integer "16" (and reads correctly into C#). This reads as 1244780 in C++ (not the memory address, I checked). Why would this be? Is there an equivalent to BinaryReader in C++? I noticed it mentioned on msdn, but that's Visual C++ and intellisense doesn't even look like c++, to me.

Example code for writing the file (C#):

    public static void OpenFile(string filename)
        fs = new FileStream(filename, FileMode.Create);
        w = new BinaryWriter(fs);


    public static void WriteHeader()

    public static byte[] RawSerialize(object structure)
        Int32 size = Marshal.SizeOf(structure);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(structure, buffer, true);
        byte[] data = new byte[size];
        Marshal.Copy(buffer, data, 0, size);
        return data;

    public static void WriteToFile(Structures.SomeData data)
        byte[] buffer = Serializer.RawSerialize(data);

I'm not sure how I could show you the data file.

Example of reading the data back (C#):

        BinaryReader reader = new BinaryReader(new FileStream("C://chris.dat", FileMode.Open));
        char[] a = new char[2];
        a = reader.ReadChars(2);
        Int32 numberoffiles;
        numberoffiles = reader.ReadInt32();
        Console.Write("Reading: ");
        Console.Write("NumberOfFiles: ");

This I want to perform in c++. Initial attempt (fails at first integer):

 fstream fin("C://datafile.dat", ios::in|ios::binary|ios::ate);
 char *memblock = 0;
 int size;
 size = 0;
 if (fin.is_open())
  size = static_cast<int>(fin.tellg());
  memblock = new char[static_cast<int>(size+1)];
  memset(memblock, 0, static_cast<int>(size + 1));

  fin.seekg(0, ios::beg);
  fin.read(memblock, size);
  if(!strncmp("AB", memblock, 2)){ 
   printf("test. This works."); 
  fin.seekg(2); //read the stream starting from after the second byte.
  int i;
  fin >> i;

Edit: It seems that no matter what location I use "seekg" to, I receive the exact same value.

share|improve this question
Can you show us a fragment of code (or whole code) and an example of binary file? –  coelhudo Oct 6 '09 at 13:39
I've posted some code. Not sure where I could upload the binary file to. –  Chris Oct 6 '09 at 13:50
you reading chris.dat in your c# reader and datafile.dat in your C++ reader... –  Pondidum Oct 6 '09 at 13:53
@Andy, the name discrepancies are just from my testing back and forth. –  Chris Oct 6 '09 at 13:58
Try writing just a single int to avoid having to worry about character sizes. Write it out, see if you can read it, and report back what the file looks like in a hex editor. –  Bill Oct 6 '09 at 14:20
add comment

4 Answers

up vote 5 down vote accepted

You realize that a char is 16 bits in C# rather than the 8 it usually is in C. This is because a char in C# is designed to handle Unicode text rather than raw data. Therefore, writing chars using the BinaryWriter will result in Unicode being written rather than raw bytes.

This may have lead you to calculate the offset of the integer incorrectly. I recommend you take a look at the file in a hex editor, and if you cannot work out the issue post the file and the code here.

Regarding your C++ code, do not use the >> operator to read from a binary stream. Use read() with the address of the int that you want to read to.

int i;
fin.read((char*)&i, sizeof(int));

Reading from a closed stream is also going to result in undefined behavior. You cannot call fin.close() and then still expect to be able to read from it.

share|improve this answer
A c/c++ char can handle unicode in the form of a utf-8 string. –  anno Feb 2 '10 at 10:15
add comment

This may or may not be related to the problem, but...

When you create the BinaryWriter, it defaults to writing chars in UTF-8. This means that some of them may be longer than one byte, throwing off your seeks.

You can avoid this by using the 2 argument constructor to specify the encoding. An instance of System.Text.ASCIIEncoding would be the same as what C/C++ use by default.

share|improve this answer
add comment

There are many thing going wrong in your C++ snippet. You shouldn't mix binary reading with formatted reading:

  // The file is closed after this line. It is WRONG to read from a closed file.

   printf("test. This works."); 

  fin.seekg(2); // You are moving the "get pointer" of a closed file
  int i;

  // Even if the file is opened, you should not mix formatted reading
  // with binary reading. ">>" is just an operator for reading formatted data.
  // In other words, it is for reading "text" and converting it to a 
  // variable of a specific data type.
  fin >> i;
share|improve this answer
Much thanks. I haven't worked with this kind of stuff in a long time and need these pointed out :) –  Chris Oct 6 '09 at 14:12
add comment

If it's any help, I went through how the BinaryWriter writes data here.

It's been a while but I'll quote it and hope it's accurate:

  • Int16 is written as 2 bytes and padded.
  • Int32 is written as Little Endian and zero padded
  • Floats are more complicated: it takes the float value and dereferences it, getting the memory address's contents which is a hexadecimal
share|improve this answer
The int32 being little endian and 0 padded, could this be causing some issues? Can you elaborate at all? (Sorry, haven't checked the link yet. it might be elaborated on in there) –  Chris Oct 6 '09 at 13:57
Looks like it was C++ char related and nothing to do with integers, except for the offset –  Chris S Oct 6 '09 at 17:59
add comment

Your Answer


