Topic: Files and the new C++ Standard Library


Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/08/01
Raw View
Mike Ost & Martha Wade<wade_ost@metro.net> wrote:
>I have been ... trying to figure out what the intent of the ANSI C++
>committee was in regards to working with files. How do they recommend
>opening them and reading/writing raw bytes?
>[whining omitted]

Istream and ostream are formatting services.  If you don't want
formatting, you don't want them.  The streambufs move bytes, which
sounds like what you want.  Filebuf, in particular, moves bytes to
and from files.  Maybe you should look into the interface for filebuf.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.org/
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: AllanW@my-dejanews.com
Date: 1998/08/01
Raw View
In article <35bf5ac2.0@news.metro.net>, Mike Ost <wade_ost@metro.net> wrote:
> I have been trying to wade through the sparse documentation that accompanies
> my VC++ 5.0 trying to figure out what the intent of the ANSI C++ committee
> was in regards to working with files. How do they recommend opening them and
> reading/writing raw bytes?

They don't recommend any particular technique, of course; that's up to
the programmer.  The standard specifies what will work, but with very
few exceptions it doesn't say that one way is better than another.

> My first hurdle was in figuring out that they now have two parallel
> implementations of streams: one in headers which end in '.h' and one
> without. God only knows why... Just try to search for text in VC++
> specifying a file type with no extension.

<iostream.h> and similar related header files are holdovers from
compilers that implemented C++ before the standard was complete.
They won't go away for a very long time (perhaps never), but it is
not part of the standard.

<iostream> and similar related header files are the relevant headers
defined by the standard. They does essentially the same thing that
<iostream.h> etc. did, except that they put the symbols into
namespace std:: instead of into the global namespace. There are other
minor differences as well.

> So then I found 'istream', 'ostream' and 'fstream'. Those looked good. I
> opened a file and wrote out an 'int' with operator<< and it got ASCIIized. I
> stepped through and found a sprintf() buried in the function that wrote out
> the data. So then I found the 'binary' flag and set that, but it didn't make
> any difference. Still ASCII characters.

The "insert" and "extract" operators are used only with streams of
text; iostream assumes that your classes that define these operators
know how to translate themselves to text and back again.

> Does anyone know the suggested route for dealing with this? Or perhaps a
> nice clear tutorial or book describing files in the new C++ libraries? Some
> sample code would be nice, too.

Since you want to write a compact, not-neccesarily-printable form of
your data to a file, you should probably use basic_istream<>::read()
and basic_ostream<>::write() to do your I/O. (basic_istream<> and
basic_ostream<> are both base classes of basic_iostream<>, and all
three are template classes.) Look up these functions in your compiler
documentation.

Note that even this may not be suitable for certain data types.
For instance, it wouldn't be appropriate to do this:
    void write_Foo(ostream &out, const Foo&foo) {
        out.write((const char*)&foo, sizeof(foo));
    }
if Foo or any of it's base classes have any virtual functions or
contain any pointers.

> Reporting from IOStreams hell... mike ost

Hang in there, Mike; you'll get used to it, and someday you may
even learn to like it.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "P.J. Plauger" <pjp@dinkumware.com>
Date: 1998/08/01
Raw View
Dietmar_Kuehl@my-dejanews.com wrote in article <6pq761$8gp$1@nnrp1.dejanews.com>...
> The IOStream library is great! You are struggling with a particualar
> implementation and the documentation. Unfortunately, I'm not aware of any
> tutorial explaining the standard IOStream library, except "Die C++
> Standardbibliothek", N.Josuttis, Addison-Wesley.

You can also profit from my book, The Draft Standard C++ Library. It
describes the iostreams library before it got ``templatized,'' but it is
still pretty accurate.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com/hot_news.html
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/08/01
Raw View
Mike Ost & Martha Wade wrote:
> I have been trying to wade through the sparse documentation that
> accompanies my VC++ 5.0 trying to figure out what the intent of the
> ANSI C++ committee was in regards to working with files. How do they
> recommend opening them and reading/writing raw bytes?

Two ways: iostreams or FILEs.  See <iostream> and <cstdio>.

> My first hurdle was in figuring out that they now have two parallel
> implementations of streams: one in headers which end in '.h' and one
> without. God only knows why... Just try to search for text in VC++
> specifying a file type with no extension.

The <iostream> is the new (standard) header, while the <iostream.h>
is the old (pre-standard) version of streams.  Similarly, the
<cstdio> is the standard C++ version of the C <stdio.h> header.

> So then I found 'istream', 'ostream' and 'fstream'. Those looked good.
> I opened a file and wrote out an 'int' with operator<< and it got
> ASCIIized. I stepped through and found a sprintf() buried in the
> function that wrote out the data.

That's because you're writing an 'int' to the output stream, so it
assumes you want something like 'printf("%d")', i.e., a decimal
number.  What you really want is to write a 'char' (or 'unsigned
char') to the stream, so that you'll get something like
'printf("%c")', i.e., a "raw" character code.

> So then I found the 'binary' flag and set that, but it didn't make any
> difference. Still ASCII characters.

The BINARY/TEXT flags deals with how newlines are written to the
file.  On DOS-based systems, writing a single '\n' (or 'endl')
normally results in a CR/LF pair ('\r', '\n'), since by default the
system assumes you are writing to the file in TEXT mode.  Setting
the file to BINARY mode means that writing a byte - any byte,
including '\n' - results in only one byte getting written to the
file.

For <cstdio>, you would open the file using 'fopen(name, "wb")',
where the "wb" means WRITE BINARY.  Opening a file with a mode of
"w" means WRITE TEXT mode.  Same thing for reading BINARY or TEXT
files, too.

-- David R. Tribble, dtribble@technologist.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Alberto Barbati" <albbarbZZZ@tin.it>
Date: 1998/08/01
Raw View
Mike Ost & Martha Wade ha scritto nel messaggio
<35bf5ac2.0@news.metro.net>...
>My first hurdle was in figuring out that they now have two parallel
>implementations of streams: one in headers which end in '.h' and one
>without. God only knows why... Just try to search for text in VC++
>specifying a file type with no extension.

The good one, i.e.: the newest and closer to the ANSI C++ standard
(although not exactly conformant) is the <iostream> header (and all
the files without the ".h"). The files with the ".h" extension are obsolete
and are provided by MS only for sake of compatibility with older
applications that fails to compile with the new ones. If you are writing
an application from scratch, you should include the new ones (be sure
_not_ to include also the old ones, as the conflict).
The iostream library doesn't do binary formatting as you want. (I think
this statement should be included in the FAQ if it is not already there).
I wrote some time ago a set of manipulators that do binary formatting
with the following syntax:

int i;
fstream bin("...", ios::binary);
bin >> bput(i);        // put a binary image of i
bin << bget(i);        // get a binary image of i

if someone is interested in having a look at it, I may post it.

Alberto Barbati

--
Alberto Barbati
Please remove ZZZ from my e-ddress when replying
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Dietmar_Kuehl@my-dejanews.com
Date: 1998/07/30
Raw View
Hi,
In article <35bf5ac2.0@news.metro.net>,
  "Mike Ost & Martha Wade" <wade_ost@metro.net> wrote:
> I have been trying to wade through the sparse documentation that accompanies
> my VC++ 5.0 trying to figure out what the intent of the ANSI C++ committee
> was in regards to working with files. How do they recommend opening them and
> reading/writing raw bytes?

With respect to I/O the standard C++ library defines basically two services:
- How to read/write individual bytes to some external representation. This is
  what the class 'basic_streambuf' and the derived classes is for.
- How to deal with formatted represetnation of built-in types when doing I/O.
  The logic for this is mainly found the facets provided by 'locale' objects.

The stream classes 'basic_istream', 'basic_ostream' and classes derived from
these mainly tie the externalization and the formatting together: These
classes do the coordination between the locale facets and the stream buffers.
In addition to formatted I/O, the stream classes also define an interface how
to write sequences of bytes, namely the functions 'read()' and 'write()'.
While the 'operator<<()' and 'operator>>()' functions provide a higher level
interface taking types into account, 'read()' and 'write()' are a low level
interface to the corresponding functions in 'basic_streambuf'.

Note, that the standard C++ library does not define functions to do "binary
formatting". Even when doing binary I/O, it is necessary to use data in a
certain format, which can be identical to the format used on a certain
platform. In particular, the format includes details like: - number of bytes
for the objects - ordering of bytes in multi byte objects - the details of
bits when writing floating point data in binary format (this is  also an
issue for integer data but most platforms use the same format)

Using the format flag 'ios_base::binary' does *NOT* turn on binary
formatting. It only suppresses certain conversions, mainly replacement of
CR/LF sequences by only one character. There may be other conversions
necessary on some platforms but the CR/LF conversion is the most common one.

> My first hurdle was in figuring out that they now have two parallel
> implementations of streams: one in headers which end in '.h' and one
> without. God only knows why... Just try to search for text in VC++
> specifying a file type with no extension.

The standard C++ library mandates only one implementation of streams, namely
the one in the headers without .h. Please don't mix implementation details of
one particular platform with the standard: MSVC++ does not define the
standard (the current version does not even implement it). If you want to
make statements about the standard, get the standard document. You can get it
from you national standardization body. However, it is relatively expensive
and a DWP would probably be sufficient for your purpose (see the FAQ of
comp.std.c++ for information on "DWP").

Concerning the "missing" extension to the header files: This issue has been
discussed a lot in this newsgroup. Just note that on other platforms the
extension is just for convenience and that it is not at all required that the
name <iostream> (or whatever header name) is mapped to file with that name.
The implementation is free to choose some other name, eg. 'iostream.h' or
'our_fancy_representation_of_iostream.fancy_format>'. ... but see the
discussion in news archives and, I think, the FAQ of this newsgroup for more
information on this topic.

> So then I found 'istream', 'ostream' and 'fstream'. Those looked good. I
> opened a file and wrote out an 'int' with operator<< and it got ASCIIized. I
> stepped through and found a sprintf() buried in the function that wrote out
> the data. So then I found the 'binary' flag and set that, but it didn't make
> any difference. Still ASCII characters.

The 'binary' flag MAKES a big difference! It suppresses conversion between
certain character sequences. If you want to use binary I/O, you certainly
want to open your file with 'binary' set. However, the flag does not change
the formatting used: The shift operators for streams do formatted I/O using a
human readable representation. This is not changed by the flag 'binary'.

> Does anyone know the suggested route for dealing with this? Or perhaps a
> nice clear tutorial or book describing files in the new C++ libraries? Some
> sample code would be nice, too.

The route to binary I/O is probably to define a set of classes very similar
to the stream classes, just doing binary formatting with the shift operators.
You can find a sample of this I hacked some years ago at
<ftp://ftp.informatik.uni-konstanz.de/pub/algo/personal/kuehl/binio.tgz>.
This uses XDR (external data representation) functions coming with RPC to
convert the data into a portable, binary representation. The details of XDR
are irrelevant to the general approach: The functions can be replaced by some
other encoding functions and potentially, if only one platform has to be
supported, even with functions doing nothing. However, some of the more
advanced stuff, like writing sequences, is not supported in this version (but
it should be relatively obvious how to support this).

Another approach to binary I/O using the existing IOStreams would be to
provide a "binary locale": The functions in the facets 'num_put' and
'num_get' would simply do binary formatting (eg. using XDR functions) instead
of dealing with human readable representations. I don't think that his
approach is really a good one, though. The problem is, it does not take care
of user defined inserters and extractors. This could result in a "half
binary" representation. For example, a complex number might appear as two
binary floating point values separated by a comma! The separating comma is
absolutely reasonable for human readable representations but totally
inappropriate for a binary representation.

> Reporting from IOStreams hell... mike ost

The IOStream library is great! You are struggling with a particualar
implementation and the documentation. Unfortunately, I'm not aware of any
tutorial explaining the standard IOStream library, except "Die C++
Standardbibliothek", N.Josuttis, Addison-Wesley. This book is in German... An
English version of this book is nearly finished and will probably appear this
year (probably "The Standard C++ Library", N.Josuttis, Addison-Wesley). For a
reference you may have a look at the pages at <http://www.dinkumware.com/>.
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Mike Ost & Martha Wade" <wade_ost@metro.net>
Date: 1998/07/30
Raw View
I have been trying to wade through the sparse documentation that accompanies
my VC++ 5.0 trying to figure out what the intent of the ANSI C++ committee
was in regards to working with files. How do they recommend opening them and
reading/writing raw bytes?

My first hurdle was in figuring out that they now have two parallel
implementations of streams: one in headers which end in '.h' and one
without. God only knows why... Just try to search for text in VC++
specifying a file type with no extension.

So then I found 'istream', 'ostream' and 'fstream'. Those looked good. I
opened a file and wrote out an 'int' with operator<< and it got ASCIIized. I
stepped through and found a sprintf() buried in the function that wrote out
the data. So then I found the 'binary' flag and set that, but it didn't make
any difference. Still ASCII characters.

Does anyone know the suggested route for dealing with this? Or perhaps a
nice clear tutorial or book describing files in the new C++ libraries? Some
sample code would be nice, too.

Reporting from IOStreams hell... mike ost
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]