Search code examples
c++visual-studioubuntuwindow

Different results when writing to binary file using std::ofstream


When writing to binary file using std::ofstream, the results are different on Windows and Linux although they are both little endian

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

template<class T>
void Write(std::ofstream& os, T i)
{
    os.write(reinterpret_cast<const char*>(&i), sizeof(T));
}

int main(int argc, char** argv)
{
    std::ofstream geofile;
    std::string geofilename = "out.bin";
    geofile.open(geofilename.c_str());

    int v = 10;
    Write(geofile, v);

    if (geofile.is_open()) geofile.close();

    return 0;
}

On Ubuntu, the code produce "0a00 0000" and on Windows is "0d0a 0000 00". Why there is such difference and how to make them the same?


Solution

  • Line breaks on Windows are \r\n (0D 0A), but are either \r (0D) or \n (0A) on other platforms. C++ file streams operate in text mode by default, so they will perform line break conversions at runtime, converting \n to platform-native line breaks on writes, and normalizing platform-native line breaks to \n on reads.

    As you can see in your example, on Windows the byte 0A is being converted to bytes 0D 0A, but on Ubuntu no conversion is made since \n is already the native line break.

    To get the same result on all platforms, you need to open the file in binary mode to disable line break conversions, eg:

    std::ofstream geofile;
    geofile.open("out.bin", std::ios::binary);
    

    Or:

    std::ofstream geofile("out.bin", std::ios::binary);