Home > Mobile >  fstream std::ios::binary printing in ASCII ? is it working correctly?
fstream std::ios::binary printing in ASCII ? is it working correctly?

Time:09-22

i was trying to write some data to a file in binary, the following is the minimal reproducible example of the problem, i am trying to print two unsigned 64 bit integers to a binary file and read one of them again ... problem is that the data is not printed or read in binary.

#inclue <fstream>
#include <iostream>
#include <stdint.h>
#include <iomanip>

int main()
{
    uint64_t a = 1;
    uint64_t b = 2;
    uint64_t c;
    std::ofstream s("file.bin", std::ios::out | std::ios::binary);
    s << a << b;
    s.close();
    std::ifstream in("file.bin", std::ios::in | std::ios::binary);
    in >> c;
    in.close();
    std::cout << c << '\n';

    std::cin >> c;
    return 0;
}

the ouput of the above code is 12, so i checked the file using notepad, and it had 12 written in it in ASCII, not in binary, i am using the latest version of msvc2017 on windows, i tried compiling it for x86 and x64, in debug and release mode and the error persists.

so is this its intended behavior ? and do i need to cast every variable to an array of characters when printing and reading ?

CodePudding user response:

The stream input and output operators >> and << are text-based. They will write the output as text, and read the input as text. Even for binary files.

To write raw binary data use the write function. And to read the raw binary data use read:

s.write(reinterpret_cast<char const*>(&a), sizeof a);
s.write(reinterpret_cast<char const*>(&b), sizeof b);

// ...

in.read(reinterpret_cast<char*>(&c), sizeof c);

CodePudding user response:

If you look closely, and you're running Windows, you might see what std::ios::binary actually does. It tells the stream functions not to do text conversions. In particular, in text mode on Windows systems, '\n' gets written out as two bytes, 0x0D followed by 0x0A (or maybe the other way around), and on input that two-byte sequence gets translated into the single character '\n'. In binary mode there's only one character.

Stream inserters and extractors always traffic in text, not binary. To write and read values as binary you have to use the member functions named (oddly enough) write and read:

s.write((const char*)&a, sizeof(a));
s.write((const char*)&b, sizeof(b));

in.read((char*)&c, sizeof(c));
  • Related