首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ofstream重置精度

ofstream重置精度
EN

Stack Overflow用户
提问于 2012-02-09 00:26:13
回答 3查看 11.3K关注 0票数 7

我正在使用c++来操作txt文件。我需要写一些具有一定精度的数字,所以我这样做:

代码语言:javascript
复制
    ofstrem file;
    file.open(filename, ios::app);
    file.precision(6);
    file.setf(ios::fixed, ios::floafield);
    //writing number on the file.....

现在我需要写其他东西,所以我需要重置精度。我该怎么做呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-09 00:28:31

首先使用precision()检索流的原始精度值,存储它,更改它,执行插入,然后将其改回存储的值。

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2012-02-09 00:46:54

有两种可能的解决方案。如果您正在处理使用相同格式化参数的大块输出,则可以使用以下内容:

代码语言:javascript
复制
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 );
    }
};

只需在执行输出的块的顶部定义它的一个实例。

然而,大多数时候,我将定义我自己的操纵器,它派生于以下内容:

代码语言:javascript
复制
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 ;
}

实现有点棘手,因为你必须考虑到,如果在同一个表达式中使用了几个操纵器,编译器可以按它喜欢的任何顺序构造它们(并因此销毁它们)。所以:

代码语言:javascript
复制
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实现中执行它必须执行的任何操作。考虑到这一点,您可以编写如下内容:

代码语言:javascript
复制
std::cout << FFmt( 6, 2 ) << someValue << std::endl;

而不必担心保存和恢复格式化状态。

票数 4
EN

Stack Overflow用户

发布于 2012-09-21 13:02:10

一种解决方案:

代码语言:javascript
复制
std::streamsize oldPres = file.precision(2);
file.setf(ios::fixed, ios::floafield);
… code continues …
file.precision(oldPres);
file.unsetf(std::ios::fixed);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9197358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档