473,700 Members | 2,382 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

std::ios::binar y?

27.4.2.1.4 Type ios_base::openm ode
Says this about the std::ios::binar y openmode flag:
*binary*: perform input and output in binary mode (as opposed to text mode)

And that is basically _all_ it says about it. What the heck does the binary
flag mean?
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 28 '05 #1
103 48654
* Steven T. Hatton:
27.4.2.1.4 Type ios_base::openm ode
Says this about the std::ios::binar y openmode flag:
*binary*: perform input and output in binary mode (as opposed to text mode)

And that is basically _all_ it says about it. What the heck does the binary
flag mean?


Basically it means that the i/o functions should not do any translation
to/from external representation of the data: they should behave as they
really should have behaved by default, but unfortunately do not.

For example, a Windows text file has each line terminated by carriage return
+ linefeed, as opposed to just linefeed in Unix, and in text mode '\n' is
translated accordingly for output, and these sequences are translated to
'\n' on input -- in practice '\r' is carriage return and '\n' is linefeed.

Also, for example, in a Windows text file Ctrl Z denotes end-of-file.
That's useful for including a short descriptive text snippet at the start of
a binary file, but I suspect it was originally a misunderstandin g of the
Unix shell command to send the current line immediately (which for an empty
line means zero bytes, which in Unix indicates end-of-file). So in text
mode in Windows, a Ctrl Z might be translated to end-of-file on input.

Interestingly the C++ iostream utilities are so extremely badly designed
that you can't make a simple copy-standard-input-to-standard-output-exactly
program using only the standard C++ library, on systems where this is
meaningful but text translation occurs in text mode.

Of course, the religious C++'ers maintain that that shouldn't be possible
anyway because you can't do it on, say, a mobile phone, where C++ could be
used for something, but then they forget that i/o is there for a reason.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 28 '05 #2
Steven T. Hatton wrote:
27.4.2.1.4 Type ios_base::openm ode
Says this about the std::ios::binar y openmode flag:
*binary*: perform input and output in binary mode (as opposed to text mode)

And that is basically _all_ it says about it. What the heck does the binary
flag mean?


On some platforms "\n" translates to "\r\n" when written (and the
reverse when read) to a file while on others it does not. binary mode
will make no such translation.
Jul 28 '05 #3
Gianni Mariani wrote:
Steven T. Hatton wrote:
27.4.2.1.4 Type ios_base::openm ode
Says this about the std::ios::binar y openmode flag:
*binary*: perform input and output in binary mode (as opposed to text
mode)

And that is basically _all_ it says about it. What the heck does the
binary flag mean?


On some platforms "\n" translates to "\r\n" when written (and the
reverse when read) to a file while on others it does not. binary mode
will make no such translation.


Is that per the Standard, or "implementa tion imposed"? I know that what you
describe is what I typically think of when I think of binary I/O. For
example, in ancient times we used to have to explicitly tell ftp to use
binary mode transfer.

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 28 '05 #4
Alf P. Steinbach wrote:
* Steven T. Hatton:
27.4.2.1.4 Type ios_base::openm ode
Says this about the std::ios::binar y openmode flag:
*binary*: perform input and output in binary mode (as opposed to text
mode)

And that is basically _all_ it says about it. What the heck does the
binary flag mean?
Basically it means that the i/o functions should not do any translation
to/from external representation of the data: they should behave as they
really should have behaved by default, but unfortunately do not.

For example, a Windows text file has each line terminated by carriage
return + linefeed, as opposed to just linefeed in Unix, and in text mode
'\n' is translated accordingly for output, and these sequences are
translated to
'\n' on input -- in practice '\r' is carriage return and '\n' is
linefeed.


Yes. I am aware of DOS spiders. ^M is what it looks like in Emacs, and it
is never a nice thing to have in a tarball. dos2unix is a great tool.
Also, for example, in a Windows text file Ctrl Z denotes end-of-file.
That's useful for including a short descriptive text snippet at the start
of a binary file, but I suspect it was originally a misunderstandin g of
the Unix shell command to send the current line immediately (which for an
empty
line means zero bytes, which in Unix indicates end-of-file). So in text
mode in Windows, a Ctrl Z might be translated to end-of-file on input.

Interestingly the C++ iostream utilities are so extremely badly designed
that you can't make a simple
copy-standard-input-to-standard-output-exactly program using only the
standard C++ library, on systems where this is meaningful but text
translation occurs in text mode.
I'm now wondering if I really understood. If I read "characters " from a
std::istream, it goes into an error state when it hits an EOF. That's why
stuff like this works (when it works)

std::vector<flo at_pair> positions
(istream_iterat or<float_pair> (file),
(istream_iterat or<float_pair> ()));

I don't believe binary files are terminated by a special character, but I
could be wrong (again).

Take this example:
############### ############### ######
Thu Jul 28 06:03:39:> cat main.cpp
#include <fstream>
#include <vector>
#include <iterator>
#include <iostream>
#include <sstream>

using namespace std;
main(int argc, char* argv[]){
if(argc<2) { cerr << "give me a file name" << endl; return -1; }

ifstream file (argv[1],ios::binary);

if(!file) { cerr << "couldn't open the file:"<< argv[1] << endl; return
-1; }

std::vector<uns igned char> data;

copy(istream_it erator<unsigned char>(file)
, istream_iterato r<unsigned char>()
, back_inserter(d ata));

cout<<"read "<<data.size()< <"bytes of data"<< endl;

file.clear();
file.seekg(0,io s::beg);
ostringstream oss;
oss << file.rdbuf();
cout<<"read "<<oss.str().si ze()<<"bytes of data"<< endl;

}

Thu Jul 28 06:10:21:> g++ -obinio main.cpp

Thu Jul 28 06:13:04:> ./binio binio
read 22075bytes of data
read 22470bytes of data

############### ###########

Notice the second output is larger than the first.
Of course, the religious C++'ers maintain that that shouldn't be possible
anyway because you can't do it on, say, a mobile phone, where C++ could be
used for something, but then they forget that i/o is there for a reason.


I suspect there are "political" reasons things turned out the way they did.
I really don't know how much of a performance hit it would be if certain
platforms had to do some extra endian shuffling. I do believe the lack of
real binary I/O in the Standard Library is an unexpected inconvenience.
Stroustrup bluntly states that binary I/O is beyond the scope of C++
Standard, and beyond the scope of TC++PL(SE). 21.2.1

Here's an interesting observation:
compiled with gcc 3.3.5
-rwxr-xr-x 1 hattons users 40830 2005-07-28 06:22 binio-3.3.5
compiled with gcc 4.0.1
-rwxr-xr-x 1 hattons users 22470 2005-07-28 06:23 binio-4.0.1

And 4.0.1 produces (much) faster code as well.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 28 '05 #5
* Steven T. Hatton:
* Alf P. Steinbach:
[snip] For example, a Windows text file has each line terminated by carriage
return + linefeed, as opposed to just linefeed in Unix, and in text mode
'\n' is translated accordingly for output, and these sequences are
translated to
'\n' on input -- in practice '\r' is carriage return and '\n' is
linefeed.
Yes. I am aware of DOS spiders. ^M is what it looks like in Emacs,


That's because a carriage return is ASCII 13, Ctrl M.

It would be different using EBCDIC, I imagine.

;-)
[snip]
Interestingly the C++ iostream utilities are so extremely badly designed
that you can't make a simple
copy-standard-input-to-standard-output-exactly program using only the
standard C++ library, on systems where this is meaningful but text
translation occurs in text mode.


I'm now wondering if I really understood. If I read "characters " from a
std::istream, it goes into an error state when it hits an EOF. That's why
stuff like this works (when it works)

std::vector<flo at_pair> positions
(istream_iterat or<float_pair> (file),
(istream_iterat or<float_pair> ()));

I don't believe binary files are terminated by a special character, but I
could be wrong (again).


Not in Unix, and not in Windows. However a binary file can contain any byte
values, and those that look like end-of-line markers will be translated in
text mode, and the first that looks like an end-of-file marker may be
translated. All depending on the implementation.
[snip] ifstream file (argv[1],ios::binary);

if(!file) { cerr << "couldn't open the file:"<< argv[1] << endl; return
-1; }

std::vector<uns igned char> data;

copy(istream_it erator<unsigned char>(file)
, istream_iterato r<unsigned char>()
, back_inserter(d ata));

cout<<"read "<<data.size()< <"bytes of data"<< endl;

file.clear();
file.seekg(0,io s::beg);
ostringstream oss; [snip]
############### ###########

Notice the second output is larger than the first.
That's probably because the ostringstream does some text mode shenanigans;
although I haven't checked.

Of course, the religious C++'ers maintain that that shouldn't be possible
anyway because you can't do it on, say, a mobile phone, where C++ could be
used for something, but then they forget that i/o is there for a reason.


I suspect there are "political" reasons things turned out the way they did.
I really don't know how much of a performance hit it would be if certain
platforms had to do some extra endian shuffling.


? The _default_ is translation. That is, the default is the overhead &
performance hit (+ other much more evil effects) you're mentioning.

I do believe the lack of
real binary I/O in the Standard Library is an unexpected inconvenience.
Stroustrup bluntly states that binary I/O is beyond the scope of C++
Standard, and beyond the scope of TC++PL(SE). 21.2.1


There is no 21.2.1.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 28 '05 #6
Alf P. Steinbach wrote:
* Steven T. Hatton:
I don't believe binary files are terminated by a special character, but I
could be wrong (again).


Not in Unix, and not in Windows. However a binary file can contain any
byte values, and those that look like end-of-line markers will be
translated in text mode, and the first that looks like an end-of-file
marker may be
translated. All depending on the implementation.


And they call it a "standard"? :/
[snip]
ifstream file (argv[1],ios::binary);

if(!file) { cerr << "couldn't open the file:"<< argv[1] << endl; return
-1; }

std::vector<uns igned char> data;

copy(istream_it erator<unsigned char>(file)
, istream_iterato r<unsigned char>()
, back_inserter(d ata));

cout<<"read "<<data.size()< <"bytes of data"<< endl;

file.clear();
file.seekg(0,io s::beg);
ostringstream oss;

[snip]
############### ###########

Notice the second output is larger than the first.


That's probably because the ostringstream does some text mode shenanigans;
although I haven't checked.


Sorry, I forgot one important point.
$ls -l binio-3.3.5
-rwxr-xr-x 1 hattons users 40830 2005-07-28 06:22 binio-3.3.5

###### note the file size above, and the second output value below:

$./binio-3.3.5 binio-3.3.5
read 40034bytes of data
read 40830bytes of data

As I understand things, when I do `file.rdbuf() >> oss' I am getting a raw
stream. That, too, may be implementation defined for all I know.

I suspect there are "political" reasons things turned out the way they
did. I really don't know how much of a performance hit it would be if
certain platforms had to do some extra endian shuffling.


? The _default_ is translation. That is, the default is the overhead &
performance hit (+ other much more evil effects) you're mentioning.


So is it the case that ios::binary may still not produce real binary
streams? That is, the stream could still act in some ways like a text
stream, e.g., eof?
I do believe the lack of
real binary I/O in the Standard Library is an unexpected inconvenience.
Stroustrup bluntly states that binary I/O is beyond the scope of C++
Standard, and beyond the scope of TC++PL(SE). 21.2.1


There is no 21.2.1.

TC++PL(SE).

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 28 '05 #7
"Steven T. Hatton" <ch********@ger mania.sup> wrote in message
news:BI******** ************@sp eakeasy.net...
27.4.2.1.4 Type ios_base::openm ode
Says this about the std::ios::binar y openmode flag:
*binary*: perform input and output in binary mode (as opposed to text
mode)

And that is basically _all_ it says about it. What the heck does the
binary
flag mean?


"Binary" and "text" are both terms of art from the C Standard, which
is included by reference in the C++ Standard. Binary I/O is byte
transparent, with the possible exception of padding NUL bytes.
Text I/O endeavors to translate between internal newline-delimited
text lines and however the system commonly represents text outside
the program.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Jul 28 '05 #8
"Alf P. Steinbach" <al***@start.no > wrote in message
news:42******** ********@news.i ndividual.net.. .
* Steven T. Hatton:
27.4.2.1.4 Type ios_base::openm ode
Says this about the std::ios::binar y openmode flag:
*binary*: perform input and output in binary mode (as opposed to text
mode)

And that is basically _all_ it says about it. What the heck does the
binary
flag mean?
Basically it means that the i/o functions should not do any translation
to/from external representation of the data: they should behave as they
really should have behaved by default, but unfortunately do not.

For example, a Windows text file has each line terminated by carriage
return
+ linefeed, as opposed to just linefeed in Unix, and in text mode '\n' is
translated accordingly for output, and these sequences are translated to
'\n' on input -- in practice '\r' is carriage return and '\n' is
linefeed.

Also, for example, in a Windows text file Ctrl Z denotes end-of-file.
That's useful for including a short descriptive text snippet at the start
of
a binary file, but I suspect it was originally a misunderstandin g of the
Unix shell command to send the current line immediately (which for an
empty
line means zero bytes, which in Unix indicates end-of-file).


No, the usage originated in early systems that couldn't describe the
length of a file to the nearest byte. A CTL-Z delimited the logical
end of text, so your program didn't read trailing garbage.
So in text
mode in Windows, a Ctrl Z might be translated to end-of-file on input. Interestingly the C++ iostream utilities are so extremely badly designed
that you can't make a simple
copy-standard-input-to-standard-output-exactly
program using only the standard C++ library, on systems where this is
meaningful but text translation occurs in text mode.
Well, yes you can. Open files in binary mode and use read/write.
Of course, the religious C++'ers maintain that that shouldn't be possible
anyway because you can't do it on, say, a mobile phone, where C++ could be
used for something, but then they forget that i/o is there for a reason.


Nonsense.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Jul 28 '05 #9
"Steven T. Hatton" <ch********@ger mania.sup> wrote in message
news:EJ******** ************@sp eakeasy.net...
Gianni Mariani wrote:
Steven T. Hatton wrote:
27.4.2.1.4 Type ios_base::openm ode
Says this about the std::ios::binar y openmode flag:
*binary*: perform input and output in binary mode (as opposed to text
mode)

And that is basically _all_ it says about it. What the heck does the
binary flag mean?
On some platforms "\n" translates to "\r\n" when written (and the
reverse when read) to a file while on others it does not. binary mode
will make no such translation.


Is that per the Standard, or "implementa tion imposed"?


The C and C++ Standards both require that text mode I/O do whatever
is necessary to convert between the universal internal form of text
streams and whatever the execution environment requires instead.
I know that what you
describe is what I typically think of when I think of binary I/O. For
example, in ancient times we used to have to explicitly tell ftp to use
binary mode transfer.


And you still do, sometimes, if your FTP utility can't make an
intelligent guess.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Jul 28 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.