# fstream issue under 64-bits cygwin

This is a question I posted on StackOverflow: fstream issue under 64-bits cygwin, glad to get help from Nemo on Stackflow, all credits goes to him.

The problem is when I use 64-bits g++ to compile the same piece of code, I get unexpected different result.

The source code looks like this:

#include
#include
using namespace std;

int main()
{
int rows = 200;
int cols = 200;
float data[rows*cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
data[i*cols+j] = i*cols+j;
}
}
const char *file = "tmp.txt";
ofstream fs(file);
if (fs.is_open())
{
fs.write((char*)&rows, sizeof(int));
cout << fs.tellp() << endl;
fs.write((char*)&cols, sizeof(int));
cout << fs.tellp() << endl;
fs.write((char*)data, sizeof(float)*rows*cols);
cout << fs.tellp() << endl;
fs.close();
}
return 0;
}
</pre>

I am writing two integers and a block of float values into a binary file. It prints out how many bytes it wrote.

The expected result is:

4
8
160008

All the actions were performed under Cygwin. When the code was compiled with g++.exe, the result is right.

But when I use x86_64-w64-mingw32-g++.exe (only by which can generate 64-bits binary), the result is wired.

4
8
160506

It is wired.

According to Nemo's answer, this is because by default fstream will be opened in binary mode under *nix. This also holds for 32 bits g++ under Cygwin, but not for 64 bits cygwin g++.

It leads to an unexpected behavior, fstream will replace some special bytes, say 'newline' in the binary data, with different special bytes, say 'unix-style newline'.

To solve this problem, replace the line
ofstream fs(file);

with

ofstream fs(file,ios_base::binary);

We can alter the content of the float data array to see what will happen.
#include
#include
using namespace std;

int main()
{
int rows = 200;
int cols = 200;
float data[rows*cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
data[i*cols+j] = 0;
}
}
const char *file = "tmp.txt";
ofstream fs(file);
if (fs.is_open())
{
fs.write((char*)&rows, sizeof(int));
cout << fs.tellp() << endl;
fs.write((char*)&cols, sizeof(int));
cout << fs.tellp() << endl;
fs.write((char*)data, sizeof(float)*rows*cols);
cout << fs.tellp() << endl;
fs.close();
}
return 0;
}
</pre>

The output is:
4
8
160208

It somehow supports the above explanation.