5

I know the extraction operator should not be used on an input stream opened in binary mode, but the member function read should be used instead.

std::ifstream ifs("file.bin", std::ios::in | std::ios::binary);
char c;
ifs >> c; // Should not be used
ifs.read(&c, 1); // OK

But it can be done anyway. So my question is what is the rationale for not unsetting the skipws flag on input file streams when opened in binary mode?

Antonio Pérez
  • 6,702
  • 4
  • 36
  • 61

1 Answers1

7

"Binary" mode, as controlled by std::ios_base::binary is only for switching off the translation of newlines between the standard C++ \n character and the system specific newline sequence as stored in files.

It's completely independent of whether you are parsing a file that contains meaningful separating whitespace or some completely different byte format so there's no reason to tie the two orthogonal pieces of functionality together.

(The C++ standard doesn't say much about what binary mode means, there is more detail in the C standard which talks about the potential differences between text streams and binary streams. Binary streams must read back byte for byte as they were written on any given system whereas text stream need only do so given a number of restrictions centring around not having extra spaces before a newline and not having any control characters other than newlines and tabs. A system need not make any distinction at all between binary and text streams.)

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 2
    As I understand a file to be binary is for its contents not to be interpreted as text, hence I got puzzled when first character extracted from a binary input stream was not a white space (0x20), as I was expecting. If the binary mode for the C++ standard is considered as you said, that´s fine, but still puzzling :) – Antonio Pérez Aug 31 '11 at 08:17
  • 1
    "A system need not make any distinction at all between binary and text streams" - and IIRC Posix requires that for FILE* and file descriptors, there is no difference between a file opened in text and binary mode. It would be a shame if that went out the window for C++ file streams due to binary files having the skipws bit set and text ones not. I think that basically there's a conflict - binary mode says "don't mess about with the bytes in my file", but `operator>>` says, "oh yes, do all manner of messing about". Hence the advice not to mix them, I suppose. – Steve Jessop Aug 31 '11 at 08:31
  • @SteveJessop: I think it's more helpful to view the translation that binary mode does as a low-level function. After all, it happens below the `streambuf` level, not even at the `istream` level where `operator>>` functions. `operator>>` is doing parsing at a higher level as it's a formatted input function. If you want to do a character by character read then you would want an unformatted read function (such as one of the `get` functions) instead but you still might be operating on a text file. I've used text mode files but the low level `streambuf::sbumpc` interface for several applications. – CB Bailey Aug 31 '11 at 08:46
  • I agree, however, that where you are doing a real byte-by-byte binary format it almost always makes sense to use `std::ios_base::binary` and unformatted input functions together. Occasionally it might make sense to use `operator>>` with a binary file, e.g. you've got to a point where you know that want to extract an ASCII decimal formatted integer or you actively need to skip to a non-whitespace character. – CB Bailey Aug 31 '11 at 08:51
  • True. I disagree anyway with "the extraction operator should not be used on an input stream opened in binary mode". Text mode is for dealing with quirks in OS conventions on line-based files. `operator>>` is usually used for reading whitespace-separated fields within a line. So the two are independent as far as that goes, but there is a use case for raw byte access (reading an mpeg file, say). For that purpose of course you don't want either kind of abstraction, so if we imagine that this is what someone considers binary mode to be "for", I think then they'd say `>>` undermines binary mode. – Steve Jessop Aug 31 '11 at 08:58