Flow accuracy reset

I use C ++ to manage txt files. I need to write some numbers with a certain accuracy, so I do:

ofstrem file; file.open(filename, ios::app); file.precision(6); file.setf(ios::fixed, ios::floafield); //writing number on the file..... 

Now I need to write another material, so I need to reset the accuracy. How can i do this?

+4
source share
3 answers

Retrieve the original value of the stream accuracy first using precision() , save it, modify it, make your insertions, and then return it to the saved value.

 int main() { std::stringstream ss; ss << 1.12345 << " "; std::streamsize p = ss.precision(); ss.precision(2); ss << 1.12345 << " "; ss.precision(p); ss << 1.12345; cout << ss.str(); // 1.12345 1.1 1.12345 } 

Live demo

+7
source

There are two possible solutions. If you are processing a large output block that uses the same formatting options, 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 that performs the output.

In most cases, I will define my own manipulator, which comes 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 complicated, since you have to consider that if several manipulators are used in one expression, the compiler can build them (and thus destroy them) in any order. 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 resulting manipulator then does everything it needs when implementing setState . Given this, you can write things like:

 std::cout << FFmt( 6, 2 ) << someValue << std::endl; 

without worrying about saving and restoring the formatting state.

+4
source

One solution:

 std::streamsize oldPres = file.precision(2); file.setf(ios::fixed, ios::floafield); … code continues … file.precision(oldPres); file.unsetf(std::ios::fixed); 
+1
source

Source: https://habr.com/ru/post/1395439/


All Articles