Open a file in binary mode

  • Thread starter Hatzigiannakis Nikos
  • Start date
H

Hatzigiannakis Nikos

I have written the following code in DEV C++ but the produced file is a
normal text file (you can type it in command line). I was expecting that the
numeric values would have written in their binary internal representation
and not as pure text.



What have I done wrong?



#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

main ()
{
ofstream myfile;
myfile.open("datafile",ios::eek:ut|ios::binary);
myfile<<123<<34<<12.123<<"start"<<endl;
myfile<<"end";
myfile.close();
}
 
I

Ian Collins

Hatzigiannakis said:
I have written the following code in DEV C++ but the produced file is a
normal text file (you can type it in command line). I was expecting that the
numeric values would have written in their binary internal representation
and not as pure text.



What have I done wrong?



#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

main ()
{
ofstream myfile;
myfile.open("datafile",ios::eek:ut|ios::binary);

This sets the file mode, not the stream.
 
G

Gianni Mariani

Hatzigiannakis said:
and how can I have a binary stream?!

Usually you use the read() and write() methods to do that.

It can be tricky to get it right, what exactly are you trying to do ?
 
H

Hatzigiannakis Nikos

was trying to demonstrate the difference between the two modes. I cannot
see any since the output is exactly the same either in text or binary mode,
in the given code
 
P

Pete Becker

was trying to demonstrate the difference between the two modes. I cannot
see any since the output is exactly the same either in text or binary mode,
in the given code

Inserters do formatting, regardless of whether the stream is in binary
or text mode. write() outputs binary data, regardless of whether the
stream is in binary or text mode.

The difference between the two modes is whether the stream translates
"special" characters. In particular, '\n' represents a newline, and in
text mode the stream writes whatever is appropriate on the system where
it's running to represent the end of a line. In binary mode it's just
the value \x0D.
 
R

red floyd

Pete said:
The difference between the two modes is whether the stream translates
"special" characters. In particular, '\n' represents a newline, and in
text mode the stream writes whatever is appropriate on the system where
it's running to represent the end of a line. In binary mode it's just
the value \x0D.

Uh, Pete, isn't that '\x0a'? I thought '\r' was '\x0d'.
 
P

Pete Becker

Uh, Pete, isn't that '\x0a'? I thought '\r' was '\x0d'.

You're probably right. But on further reflection, it's neither. For
some reason I thought the standard specified the value of '\r' and
'\n'. But that's a hallucination. The value depends on the compiler.
 
R

red floyd

Pete said:
You're probably right. But on further reflection, it's neither. For some
reason I thought the standard specified the value of '\r' and '\n'. But
that's a hallucination. The value depends on the compiler.

That makes sense, since it would be dependent on the execution character
set (0x0a and 0x0d are ASCII, but EBCDIC would probably be quite different).
 
J

James Kanze

On 2007-11-13 06:39:45 -0500, "Hatzigiannakis Nikos" <[email protected]> said:
Inserters do formatting, regardless of whether the stream is in binary
or text mode. write() outputs binary data, regardless of whether the
stream is in binary or text mode.

And when writing to a file, the embedded locale does code
translation, regardless of the mode or whether you use inserts
or unformatted output functions. (A name which I detest. All
output has a format. If you use write() carelessly, you may end
up not knowing the format, but it does have a format.)
The difference between the two modes is whether the stream translates
"special" characters.

There's a lot more to it than that. On some systems, different
files types might be used, and it may not be possible to open in
text mode a stream written in binary, and vice versa. On other
systems (including all Unix and Unix-like systems), there's
absolutely no difference, the two modes are indistiguishable.
In particular, '\n' represents a newline,
Internally.

and in text mode the stream writes whatever is appropriate on
the system where it's running to represent the end of a line.

Again, it's more subtle than that. According to the (C)
standard: "A text stream is an ordered sequence of characters
composed into lines, each line consisting of zeor or more
characters plus a terminating new-line character." A text stream
is only guaranteed to work if the data written consists only of
printing characters, '\t' and '\n', no '\n' is immediatly
preceded by a space character, and the last character is a '\n'.
You cannot simply write arbitrary binary data to a text stream.
And what is physically on the disk may be different from what
you would see if you dumped the buffer from memory. (At least
one implementation of C for an IBM mainframe used ASCII
internally, and translated to EBCDIC when it output to disk.
Lines in text files were mapped to fixed length records on the
disk, with each line spaced padded to the record
length---trailing spaces were stripped on input---and no
characters whatever for the '\n'. The standard was carefully
designed to allow such implementations.)

In practice: Unix treats text mode as binary. (Unix also
requires an encoding derived from ASCII, with '\n' being
represented as 0x0A, '\r' as 0x0D, '\t' as 0x09, etc. This is a
Posix requirement, however, not a C/C++ one.) Windows maps '\n'
to the two byte sequence 0x0D, 0x0A, and recognizes 0x1A as an
end of file on input.

A binary stream just dumps whatever you give it to the output
(modulo code translation by the embedded locale). On the other
hand, it's not required to have a reliable end of file: you may
read more than you wrote (but the additional bytes are
guaranteed to be 0. This is a sop to some older OS's (CP/M, but
I think some DEC OS's as well), which maintained the file size
as a number of sectors, not bytes.
In binary mode it's just the value \x0D.

Not on my machines. It's been 0x0A on every system I've seen.
(If the machine used EBCDIC internally, it would probably be
0x15.) But most accurately, it's '\n'. Everywhere. If you're
writing text, you use it to indicate the end of the line, and
the system does the rest. If you're writing in binary mode, you
don't use it, directly.

In theory, at least. In practice, as I said, I've never seen an
actual implementation where it wasn't 0x0A.
 
A

Alf P. Steinbach

* James Kanze -> Pete Becker:
[snip]
There's a lot more to it than that.

[snip large pedantic detailing and correction of basics]

Fetching popcorn... :)

Cheers,

- Alf
 
P

Pete Becker

And when writing to a file, the embedded locale does code
translation, regardless of the mode or whether you use inserts
or unformatted output functions.

And since it's not affected by the mode, it's irrelevant to this discussion.
There's a lot more to it than that.

Indeed. But giving long technical explanations to beginners is a good
way to discourage them.
Again, it's more subtle than that.

Again, fully detailed explanations are often counterproductive.
Not on my machines. It's been 0x0A on every system I've seen.

This has already been dealt with in two followup messages. But thanks
for piling on.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top