Topic: iostream EOF's
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/12/15 Raw View
Joe Keane <jgk@jgk.org> writes:
|> In article <m3lnxxrr8q.fsf@gabi-soft.fr>
|> J. Kanze <kanze@gabi-soft.fr> writes:
|> >If you find using shift operators esthetically (or stylisticly)
|> >displeasing, then I'd also agree.
|>
|> The problem is, they can't do operations that involve more than the
|> stream and value to be printed, which is, i would say, most operations.
|> If you use `print' methods, you can always add optional arguments for
|> flags, width, precision, or whatever is relevant *to that method*.
You can do this with iostream, as well, although historically, no one
does. Basically: create a FormattingDouble class, whose constructors
take the extra arguments, and output that:
cout << FormattingDouble( x , desiredWidth , desiredPrecision ) ;
This was actually the way I thought iostream's were meant to work, until
I learned better:-).
|> >However, there is a fundamental simplification: the sink/source
|> >abstraction is separate from the formatting abstraction.
|>
|> There's no separation. It's a good idea, but it's not there.
What is the difference between ios and its derivatives, and streambuf,
then?
|> >For that matter, the use of state makes also makes iostream simpler to
|> >understand, although IMHO, it leads to enough other complications that
|> >I would prefer avoiding it.
|>
|> I don't think it's simpler to understand, and the main complication is
|> that it doesn't work. If you write a method to print a complex number,
|> or a vector, in the obvious way, any state that the user sets affects
|> only the first component. This behavior is not especially intuitive.
|>
|> To make it work, you have to pull the desired state into some local
|> variables, then store it back at the right points, perhaps doing this at
|> several levels. This ends up looking like some amateur BASIC program.
|> It is not simpler and it takes up run time for no good reason.
I agree that writing good inserters and extractors is not trivial. A
good complex inserter, for example, has to get the width, subtract some
fixed overhead, divide it by two, and reset it before formatting each
double.
But it is possible (and not that complicated, once you are aware of the
issues). Which is more than you can say for printf.
|> >One nice advantage of the separation of the abstractions is that if you
|> >don't like the formatting, you can easily roll your own, using the
|> >existing code for the actual work, and it will work seemlessly with
|> >other code using the standard iostream.
|>
|> I can't add new state. If some operation has a `width', i can use the
|> existing attribute in the stream, but if it also has a `height', i can't
|> do it the same way. The streams are tied to the formats that are there.
Of course you can. That's what xalloc and company are there for.
|> Of course i can pass things as arguments to `print' methods. I think
|> that's the better way, but it's not consistent with what's there.
Again, I sort of agree. I think that it might have been better to have
used formatting classes, as above. While I have some code which very
much counts on the fact that I can set flags, then output some unknown
type (in template code), and expect it to format correctly, it is a
pretty sophisticated application, and probably doesn't justify making
things less intuitive for the normal case.
It's interesting that you haven't mentioned what is, to me, the biggest
problem with using state: you must save and restore it if you are
modifying it. And that if the type uses some state allocated with
xalloc, you don't even necessarily know what you have to save and
restore.
Finally, of course, there is the problem of arguments not occuring in
the same order in different langauges. While the C standard doesn't
support this for printf, either, X/Open (and maybe Posix) have a simple
extension that does. I do not think it possible to do the same with
iostream without completely rethinking the formatting interface.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientie objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/12/15 Raw View
Pete Becker <petebecker@acm.org> writes:
|> Joe Keane wrote:
|> >
|> > I can't add new state. If some operation has a `width', i can use the
|> > existing attribute in the stream, but if it also has a `height', i can't
|> > do it the same way. The streams are tied to the formats that are there.
|>
|> Take a look at xalloc(), iword(), and pword(). They're not very well
|> known, but iostream states have always been extendable.
I think that Pete has put his hand on the biggest single problem with
iostream: much of what it can do is not very well know.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientie objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/12/16 Raw View
jodle@bix.com (jodle) writes:
|> J. Kanze (kanze@gabi-soft.fr) wrote:
|> : Joe Keane <jgk@jgk.org> writes:
|>
|> : One nice advantage of the separation of the abstractions is that if you
|> : don't like the formatting, you can easily roll your own, using the
|> : existing code for the actual work, and it will work seemlessly with
|> : other code using the standard iostream. Try doing that with printf.
|>
|> I've always liked and been impressed by the power, structure and
|> extensibility of the iostream library, particularly in the oft-overlooked
|> strstream classes. With the single exception of the design of strstream
|> with regard to dynamic allocation and the use of str() which seems to be
|> intended to leak memory (a feature addressed by the standard), strstreams
|> are far more powerful and intuitive than their C string.h counterparts.
|>
|> I have implemented my own formatting classes to use with streambuf classes
|> and my own streambuf classes to use with istream/ostream classes. While
|> it's true these can be leveraged to great effect, little can be done with
|> ios in as straightforward a manner since its relationship with the buffer
|> and formatting classes is familial rather than delegatory. It is abstract
|> enough that it doesn't usually get itself in the way, though.
I don't understand the comment "familial rather than delegatory". The
formatting classes (istream and ostream) very definitly delegate the
sinking and sourcing to streambuf, a separate class, used, but not
(necessarily) owned by them.
Part of the implementation of my formatting class uses a template, which
(roughly) converts my formatting to a call to operator<< on an ostream.
Since my formatting class doesn't necessarily output the values in the
order they are converted, this is an ostrstream in the test versions --
the final version will use an optimized streambuf, which contains enough
local memory for most cases (thus avoiding a dynamic allocation
entirely), and offers extra functions for the formatting class to know
when one ostream starts and the preceding leaves off. In this way, my
formatting class is able to leverage off the existing formatting
classes. (It also provides the hooks for the user who wants to pass
additional info to the formatting function.)
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient e objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: ncm@best.com (Nathan Myers)
Date: 1997/12/13 Raw View
In article <348DEE55.D94403CA@ix.netcom.com>,
Paul D. DeRocco <pderocco@ix.netcom.com> wrote:
>I think the C++ method of storing the format state in the stream is a
>kludge ... What I've always wished for (and have written for myself)
>are helper classes that combine the format parameters with the data.
> ... This lets me write things like:
>
> cout << "Memory address = " << Hex(addr, 8) << '\n';
>
>which is less modal, and I think more readable, than the standard way.
This is in fact the recommended way to package up any format request
you need more than once. It's just not the default, for reasons that
will be evident if you think it through.
Nathan Myers
ncm@nospam.cantrip.org
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: jodle@bix.com (jodle)
Date: 1997/12/13 Raw View
J. Kanze (kanze@gabi-soft.fr) wrote:
: Joe Keane <jgk@jgk.org> writes:
: One nice advantage of the separation of the abstractions is that if you
: don't like the formatting, you can easily roll your own, using the
: existing code for the actual work, and it will work seemlessly with
: other code using the standard iostream. Try doing that with printf.
I've always liked and been impressed by the power, structure and
extensibility of the iostream library, particularly in the oft-overlooked
strstream classes. With the single exception of the design of strstream
with regard to dynamic allocation and the use of str() which seems to be
intended to leak memory (a feature addressed by the standard), strstreams
are far more powerful and intuitive than their C string.h counterparts.
I have implemented my own formatting classes to use with streambuf classes
and my own streambuf classes to use with istream/ostream classes. While
it's true these can be leveraged to great effect, little can be done with
ios in as straightforward a manner since its relationship with the buffer
and formatting classes is familial rather than delegatory. It is abstract
enough that it doesn't usually get itself in the way, though.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/12/07 Raw View
Joe Keane <jgk@jgk.org> writes:
|> In article <m3hg8ukuxk.fsf@gabi-soft.fr>
|> J. Kanze <kanze@gabi-soft.fr> writes:
|> >Yes. The separation of abstraction (formatting vs. data sink/source)
|> >introduces such complexity that there is now discussion of introducing
|> >it into C.
|>
|> Ah yes, that's why C++ *streams* have state for field width, precision,
|> fill character, decimal/octal/hexadecimal base, left/right adjustment,
|> upper/lower case, and whatever else. That stupid C idea of putting
|> format information *in the format* introduces such complexity.
OK. If that's your complaint about iostream's, then I mostly agree. If
you find using shift operators esthetically (or stylisticly)
displeasing, then I'd also agree. However, there is a fundamental
simplification: the sink/source abstraction is separate from the
formatting abstraction. Now, I expect that this is also the case for
most implementations of printf -- the implementor really doesn't want to
have to duplicate the code in sprintf -- but it isn't really defined
this way, and the user can't leverage off the separation as he can in
C++. (There has been some discussion recently in comp.std.c about how
to change this, but it is too vague and too late to have any influence
on C9x.)
Although there are aspects I don't care for, I think that globally, the
separation of the abstraction leads to results that are simpler to
understand, if not always to use. For that matter, the use of state
makes also makes iostream simpler to understand, although IMHO, it leads
to enough other complications that I would prefer avoiding it.
One nice advantage of the separation of the abstractions is that if you
don't like the formatting, you can easily roll your own, using the
existing code for the actual work, and it will work seemlessly with
other code using the standard iostream. Try doing that with printf.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientie objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Joe Keane <jgk@jgk.org>
Date: 1997/12/10 Raw View
In article <m3lnxxrr8q.fsf@gabi-soft.fr>
J. Kanze <kanze@gabi-soft.fr> writes:
>If you find using shift operators esthetically (or stylisticly)
>displeasing, then I'd also agree.
The problem is, they can't do operations that involve more than the
stream and value to be printed, which is, i would say, most operations.
If you use `print' methods, you can always add optional arguments for
flags, width, precision, or whatever is relevant *to that method*.
>However, there is a fundamental simplification: the sink/source
>abstraction is separate from the formatting abstraction.
There's no separation. It's a good idea, but it's not there.
>For that matter, the use of state makes also makes iostream simpler to
>understand, although IMHO, it leads to enough other complications that
>I would prefer avoiding it.
I don't think it's simpler to understand, and the main complication is
that it doesn't work. If you write a method to print a complex number,
or a vector, in the obvious way, any state that the user sets affects
only the first component. This behavior is not especially intuitive.
To make it work, you have to pull the desired state into some local
variables, then store it back at the right points, perhaps doing this at
several levels. This ends up looking like some amateur BASIC program.
It is not simpler and it takes up run time for no good reason.
>One nice advantage of the separation of the abstractions is that if you
>don't like the formatting, you can easily roll your own, using the
>existing code for the actual work, and it will work seemlessly with
>other code using the standard iostream.
I can't add new state. If some operation has a `width', i can use the
existing attribute in the stream, but if it also has a `height', i can't
do it the same way. The streams are tied to the formats that are there.
Of course i can pass things as arguments to `print' methods. I think
that's the better way, but it's not consistent with what's there.
--
Joe Keane, amateur mathematician
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/12/10 Raw View
J. Kanze wrote:
>
> Although there are aspects I don't care for, I think that globally, the
> separation of the abstraction leads to results that are simpler to
> understand, if not always to use. For that matter, the use of state
> makes also makes iostream simpler to understand, although IMHO, it leads
> to enough other complications that I would prefer avoiding it.
I think the C++ method of storing the format state in the stream is a kludge
whose primary benefit is that it allows the "cute" trick of including
manipulators in a chain of << operators. The problem arises when you want to
implement your own inserter that uses built-in ones internally. Typically, you
have to save the format state variables, set them the way you want, do your
output, and then restore the variables. What I've always wished for (and have
written for myself) are helper classes that combine the format parameters with
the data. For instance:
struct Hex {
unsigned long value;
unsigned char width;
bool upper;
Hex(unsigned long v, unsigned char w, bool u = true):
value(v) width(w), upper(u) {}
};
ostream& operator<<(ostream& os, HexN h);
This lets me write things like:
cout << "Memory address = " << Hex(addr, 8) << '\n';
which is less modal, and I think more readable, than the standard way.
--
Ciao,
Paul
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Pete Becker <petebecker@acm.org>
Date: 1997/12/10 Raw View
Joe Keane wrote:
>
> I can't add new state. If some operation has a `width', i can use the
> existing attribute in the stream, but if it also has a `height', i can't
> do it the same way. The streams are tied to the formats that are there.
Take a look at xalloc(), iword(), and pword(). They're not very well
known, but iostream states have always been extendable.
-- Pete
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/12/01 Raw View
Joe Keane <jgk@jgk.org> writes:
|> In article <65715m$srq@lotho.delphi.com>
|> jodle <jodle@bix.com> writes:
|> >That would mean that two iostream implementations might handle end-of-file
|> >correctly. I would then drop dead from the shock.
|>
|> I would die of shock if two users of iostreams understand it.
Yes. The separation of abstraction (formatting vs. data sink/source)
introduces such complexity that there is now discussion of introducing
it into C.
For those who don't understand irony: iostream is significantly simpler
to understand, if not always to use, than printf and company.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientie objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Joe Keane <jgk@jgk.org>
Date: 1997/12/03 Raw View
In article <m3hg8ukuxk.fsf@gabi-soft.fr>
J. Kanze <kanze@gabi-soft.fr> writes:
>Yes. The separation of abstraction (formatting vs. data sink/source)
>introduces such complexity that there is now discussion of introducing
>it into C.
Ah yes, that's why C++ *streams* have state for field width, precision,
fill character, decimal/octal/hexadecimal base, left/right adjustment,
upper/lower case, and whatever else. That stupid C idea of putting
format information *in the format* introduces such complexity.
--
Joe Keane, amateur mathematician
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/11/22 Raw View
On 21 Nov 97 04:47:24 GMT, dleimbac@falcon.lhup.edu (Dave) wrote:
>Since the standard has been passed am i correct to assume that EOF
>would represent one past the end of the data in a "file" much like the
>end memeber functions do?
When the eof bit in the stream state is set, it means the stream has
encountered the end of the file and no more input is available. When
the bit is not set, it means the stream hasn't yet discovered the end
of the file, although there might in fact be no more input available.
The function eof() returns the state of the eof bit. If you try to
attach additional significance to the eof bit or function, you can
wind up with false expectations.
Some functions return the value EOF to indicate an error. Some input
functions return EOF to indicate no data could be read -- whether
actually at end of file or due to some other problem.
---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jodle@bix.com (jodle)
Date: 1997/11/22 Raw View
Dave (dleimbac@falcon.lhup.edu) wrote:
: Since the standard has been passed am i correct to assume that EOF
: would represent one past the end of the data in a "file" much like the
: end memeber functions do?
That would mean that two iostream implementations might handle end-of-file
correctly. I would then drop dead from the shock.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Joe Keane <jgk@jgk.org>
Date: 1997/11/25 Raw View
In article <65715m$srq@lotho.delphi.com>
jodle <jodle@bix.com> writes:
>That would mean that two iostream implementations might handle end-of-file
>correctly. I would then drop dead from the shock.
I would die of shock if two users of iostreams understand it.
--
Joe Keane, amateur mathematician
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]