There are two possible solutions. If you're handling a large block of
output which uses the same formatting parameters, you can use something
like this:
class IOSave
{
std::ios& myStream;
std::ios::fmtflags myFlags;
std::streamsize myPrecision;
char myFill;
public:
IOSave( std::ios& userStream )
: myStream( userStream )
, myFlags( userStream.flags() )
, myPrecision( userStream.precision() )
, myFill( userStream.fill() )
{
}
~IOSave()
{
myStream.flags( myFlags );
myStream.precision( myPrecision );
myStream.fill( myFill );
}
};
Just define an instance of it at the top of the block doing the output.
Most of the time, however, I'll be defining my own manipulator, which
derives from something like:
class StateSavingManipulator
{
mutable std::ios* myStream;
mutable std::ios::fmtflags mySavedFlags;
mutable int mySavedPrec;
mutable char mySavedFill;
virtual void setState( std::ios& stream ) const = 0 ;
protected:
StateSavingManipulator();
public:
virtual ~StateSavingManipulator();
void operator()( std::ios& stream ) const ;
};
inline std::ostream& operator<<(
std::ostream& out,
StateSavingManip const& manip)
{
manip( out ) ;
return out ;
}
inline std::istream&
operator>>(
std::istream& in,
StateSavingManip const& manip )
{
manip( in ) ;
return in ;
}
The implementation is a bit tricky, since you have to take into account
that if several manipulators are used in the same expression, the
compiler can construct them (and thus destruct them) in any order it
pleases. So:
namespace {
int getXAlloc() ;
int ourXAlloc = getXAlloc() + 1 ;
int getXAlloc()
{
if ( ourXAlloc == 0 ) {
ourXAlloc = std::ios::xalloc() + 1 ;
assert( ourXAlloc != 0 ) ;
}
return ourXAlloc - 1 ;
}
}
StateSavingManipulator::StateSavingManipulator()
: myStream( NULL )
{
}
StateSavingManipulator::~StateSavingManipulator()
{
if ( myStream != NULL ) {
myStream->flags( mySavedFlags ) ;
myStream->precision( mySavedPrec ) ;
myStream->fill( mySavedFill ) ;
myStream->pword( getXAlloc() ) = NULL ;
}
}
void StateSavingManipulator::operator()(
std::ios& stream ) const
{
void*& backptr = stream.pword( getXAlloc() ) ;
if ( backptr == NULL ) {
backptr = const_cast< StateSavingManip* >( this ) ;
myStream = &stream ;
mySavedFlags = stream.flags() ;
mySavedPrec = stream.precision() ;
mySavedFill = stream.fill() ;
}
setState( stream ) ;
}
The derived manipulator then does whatever it has to in its implementation of setState
. Given this, you can write things like:
std::cout << FFmt( 6, 2 ) << someValue << std::endl;
without having to worry about saving and restoring the formatting state.