Topic: Help! how to cast a pointer to a file to ostream class


Author: matt@physics2.berkeley.edu (Matt Austern)
Date: 30 Mar 1994 21:37:48 GMT
Raw View
In article <JSS.94Mar21161133@summit.lucid.com> jss@lucid.com (Jerry Schwarz) writes:

> The operation you want to perform (setting up a local "copy") could
> always have been done without assignment via a constructor
>
>         ostream local( cout.rdbuf() ) ; // make a local copy
>
> This will continue to work in an implementation that conforms to the
> working paper.
>
> Stylistically  I believe it is better to save/restore the format
> state rather making such a local copy, but I'm not dogmatic about
> it.  I just hope you're careful about doing the right thing with
> the error state.

The problem with saving and restoring the format state is really in
that "restore" part.  You have to make sure, for every possible exit
path from a function (including exceptions), that you're restoring the
state of the global object you're working with.  This can be a bit of
a mess, and it's easy to miss one restore somewhere.  Far easier to
work with a local object, and be sure that changing its state isn't
going to affect something somewhere else in your program.

Stylistically, too, I don't really like the save-and-restore idea.  To
me, at least, it feels like you're using a scope, but that you're
introducing your own scoping mechanisms instead of using the ones
defined by the language.

(Actually, I'm not completely sure I like the whole idea of doing
formatting by means of format flags in a globally defined object, but
I can't think of a better alternative.)
--
Matthew Austern                       Never express yourself more clearly
matt@physics.berkeley.edu             than you think.    ---N. Bohr




Author: jss@lucid.com (Jerry Schwarz)
Date: 22 Mar 1994 00:11:32 GMT
Raw View
matt:
   I hope that istream_withassign and ostream_withassign aren't going
   to disappear: I find them very useful.


They are not included in the current working paper. However, the
latest paper contains explicit members for copying all the components
of an arbitrary ios.

        ios& ios::copyfmt(ios& in) ;    // copy the formatting info
        streambuf* ios::rdbuf(streambuf* sb); // set the streambuf
        ios::clear(iostate);           // set the error state
        ios::exception(iostate);       // set the (new) exception state

ios::rdbuf(streambuf*) is new.  It is a dangerous operation on an
arbitrary stream, but if you know what you're doing it can be useful.
Assignment of the with_assign classes has always been defined to just
copy the streambuf.

ios::copyfmt(ios&) is also new. Not only is individually copying the
formatting components tedious but the old interface provided no way to
determine how many members of the extensible arrays to copy.

ios::clear is in the existing libraries.

The exception state is a new component of streams as defined in the
working paper.

matt:
   If, for example, I want to do some special formatting, but don't
   want to change global state, then one convenient way to do things is
   to define os to be an ostream_withassign, assign cout to os, set
   os's format flags (which doesn't affect cout), and then use os
   for all of my output in that scope.

matt:
   There are other ways one could imagine doing this---for example,
   adding a new constructor, ostream::ostream(const ostream&).  Either
   way, though, I like being able to create a local copy of an ostream,
   one that outputs to the same physical place but that doesn't share
   formatting flags.

The operation you want to perform (setting up a local "copy") could
always have been done without assignment via a constructor

        ostream local( cout.rdbuf() ) ; // make a local copy

This will continue to work in an implementation that conforms to the
working paper.

Stylistically  I believe it is better to save/restore the format
state rather making such a local copy, but I'm not dogmatic about
it.  I just hope you're careful about doing the right thing with
the error state.

  -- Jerry Schwarz(jss@lucid.com)









Author: jtrsmith@garnet.berkeley.edu ()
Date: 17 Mar 1994 05:12:31 GMT
Raw View
I have a

  FILE* f = fopen(...);
  ostream g;
  g = ostream (f)  // compiler complains here saying bad functional cast.

What is the correct way to cast f to g?

Thank!

John




Author: jss@lucid.com (Jerry Schwarz)
Date: 17 Mar 1994 23:21:05 GMT
Raw View
>   I have a
>
>     FILE* f = fopen(...);
>     ostream g;
>     g = ostream (f)  // compiler complains here saying bad functional cast.
>
>   What is the correct way to cast f to g?

FILE's and streams are completely different data structures, and you
can't cast between them. Further you can't assign streams.  (Yes,
there is an ugly kludge in existing libraries that lets you assign to
cin, cout and cerr -- be warned: that isn't part of the current working
paper).

However you can create a stream based on a FILE,

    #include <iostream.h>
    #include <stdio.h>
    #include <stdiostream.h>

    ...

    FILE* f = fopen(...) ;
    stdiostream s(f) ;
    ostream& out = s ;

g will be unbuffered so output can be mixed on a character
by character basis.

  -- Jerry Schwarz(jss@lucid.com)








Author: matt@physics16.berkeley.edu (Matt Austern)
Date: 17 Mar 1994 23:46:35 GMT
Raw View
In article <JSS.94Mar17152106@summit.lucid.com> jss@lucid.com (Jerry Schwarz) writes:

> FILE's and streams are completely different data structures, and you
> can't cast between them. Further you can't assign streams.  (Yes,
> there is an ugly kludge in existing libraries that lets you assign to
> cin, cout and cerr -- be warned: that isn't part of the current working
> paper).

I hope that istream_withassign and ostream_withassign aren't going
to disappear: I find them very useful.

If, for example, I want to do some special formatting, but don't
want to change global state, then one convenient way to do things is
to define os to be an ostream_withassign, assign cout to os, set
os's format flags (which doesn't affect cout), and then use os
for all of my output in that scope.

There are other ways one could imagine doing this---for example,
adding a new constructor, ostream::ostream(const ostream&).  Either
way, though, I like being able to create a local copy of an ostream,
one that outputs to the same physical place but that doesn't share
formatting flags.
--
Matthew Austern                       Never express yourself more clearly
matt@physics.berkeley.edu             than you think.    ---N. Bohr