我正在使用c ++来操作txt文件。 我需要写一些具有一定精度的数字,所以我在做:
ofstrem file;
file.open(filename, ios::app);
file.precision(6);
file.setf(ios::fixed, ios::floafield);
//writing number on the file.....
现在我需要写其他东西,所以我需要重置精度。 我怎么能这样做?
答案 0 :(得分:7)
首先使用precision()
检索流的原始精度值,存储,更改,插入,然后将其更改回存储值。
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
}
答案 1 :(得分:4)
有两种可能的解决方案。如果你正在处理大块的 输出使用相同的格式参数,你可以使用一些东西 像这样:
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 );
}
};
只需在执行输出的块顶部定义它的实例。
然而,大多数情况下,我将定义自己的操纵器,其中 来源于:
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 ;
}
实施有点棘手,因为你必须考虑到 如果在同一个表达式中使用了几个操纵器,那么 编译器可以按任何顺序构造它们(从而破坏它们) 为所欲为。所以:
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 ) ;
}
派生的操纵器然后在setState
的实现中执行任何操作。鉴于此,您可以编写如下内容:
std::cout << FFmt( 6, 2 ) << someValue << std::endl;
无需担心保存和恢复格式化状态。
答案 2 :(得分:1)
一个解决方案:
std::streamsize oldPres = file.precision(2);
file.setf(ios::fixed, ios::floafield);
… code continues …
file.precision(oldPres);
file.unsetf(std::ios::fixed);