Re: arbitrary number of digits at integer representation
Seungbeom Kim wrote:
kanze wrote:
Carl Barron wrote:
In article <1149757047.131133.313940@y43g2000cwc.googlegroups.com>,
kanze <kanze@gabi-soft.fr> wrote:
std::string
cppFormat(
int value,
int width,
int prec )
{
std::ostringstream tmp ;
tmp << std::setfill( '0' ) << std::setw( prec ) << value ;
std::ostringstream result ;
result << std::setw( width ) << tmp.str() ;
return result.str() ;
}
Note too that it takes two separate ostringstream's to do this.
does it?? does not setting the fill and the width as
writing to an ostringstream give a string of the desired
value?
It depends on the desired value:-). If the desired value is
a string of at least width characters, with at least prec
digits, then it only gives the desired value if width and
prec are equal.
Interesting. I thought precision() would specify the minimum
number of digits, which turns out to be false. Then doesn't
precision() play any role in formatting integers?
No. Precision doesn't play any role in formatting strings,
either. If you're used to the C printf formatting, this is
surprising, to say the least.
I suspect that the reason for this is that precision is sticky.
And that people do use this "feature" when outputting a sequence
of floating point values, with integers and text interspaced.
Things like:
std::cout.setf( std::ios::fixed, std::ios::floatfield ) ;
std::cout.precision( 2 ) ;
for ( int i = 0 ; i < v.size() ; ++ i ) {
std::cout << i + 1 << " = " << v.someDouble << std::endl ;
}
If precision affected strings and ints, this would result in
something like "01 =3.14", rather than "1 = 3.14".
Having to use two separate stream objects just to format a
single integer is really frustrating. (Think of the cost of
constructing and destroying the objects!) In my opinion,
making formatting options into a 'state' of the stream objects
was a seriously bad decision; formatting should really have
been stateless, just as what a simple "%8.6d" can.
It's hard to imagine an alternative to state for communicating
between manipulators and the formatter. Probably, all state
should have been volatile, like width(). But originally, for
namespace management reasons, there weren't manipulators for
most of the stuff (and the importance of using application
specific manipulators for logical mark-up wasn't recognized).
Which meant that you had to use something like my code above to
set the flags and the precision. If the state had affected
int's and strings, and been volatile like width, you'd have had
to write something like:
cout << i + 1 << " = " ;
cout.setf( ios::fixed, ios::floatfield ) ;
cout.precision( 2 ) ;
cout << v.someDouble << endl ;
Most of the manipulators were added when namespaces were added
to the language, and iostream was moved to a specific namespace.
At that time, it probably would have been possible to make all
of them volatile -- enough other things changed that a lot of
code needed reworking anyway. But one of the goals was, I
think, to minimize the amount of rework needed; for most simpler
uses, replacing #include <iostream.h> with #include
<iostream>/#include <ostream>/using namespace std; is
sufficient.
Having to use separate stream objects or to save the states
and restore them later is too much trouble, and costly at
best.
Using separate stream objects can be expensive, although
compared to the cost of the actual IO, I'm not sure. Saving and
restoring typically isn't: you have a simple RAII-like class
which takes care of it (or you derive your manipulators from a
base class which takes care of it). And the cost in most
implementations is truly negligible; remember, all of the
functions which are involved can be easily inlined.
On the other hand, I agree that having the state stick, and
especially having some sticky, and the rest volatile, doesn't
make learning of the streams any easier.
--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]