如何使格式标志在C ++中不绑定?

时间:2011-09-15 08:44:59

标签: c++ hex

  

可能重复:
  “Roll-Back” or Undo Any Manipulators Applied To A Stream Without Knowing What The Manipulators Were

考虑以下代码

int temp=256;
cout<<temp<<endl;
cout<<hex<<temp<<endl;
cout<<temp<<endl;

输出分别为“256”,“100”和“100”。 是否可以使'hex'标志不具有约束力?

我不想明确地写'dec'。

3 个答案:

答案 0 :(得分:2)

不适用于标准操纵器。但在实践中,你可能 不应该使用标准操纵器(除了可能作为一个 例);它们对应于物理标记,在应用程序中,您 想要使用逻辑标记。你想写类似

的东西
cout << temperature << roomTemperature;

,其中温度是特定应用的操纵器,定义 (全球)如何输出温度。那样的话,如果 规格变化,需要不同的温度格式, 你只需要在一个地方改变它。调试输出有点 这里有一个例外,但即使在那里,写起来也容易得多 类似的东西:

cout << HexFmt( 4 ) << var;

大于

cout << hex << setfill( '0' ) << setw( 4 ) << var;

(你可能经常使用像HexFmt这样的东西 证明在工具箱中使用它。)

你自己写的机器人可以恢复 以前的状态,至少在完整表达结束时。我所有的 操纵者来自以下类:

StateSavingManip.hh:

class StateSavingManip : boost::noncopyable
{
    mutable std::ios*   myStream;
    mutable std::ios::fmtflags
                        mySavedFlags;
    mutable int         mySavedPrec;
    mutable char        mySavedFill;

private:
    virtual void        setState( std::ios& stream ) const = 0;

protected:
    StateSavingManip();

public:
    StateSavingManip( StateSavingManip const& other );
    virtual             ~StateSavingManip();
    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;
}

StateSavingManip.cc:

namespace {

    int                 getXAlloc();
    int                 ourXAlloc = getXAlloc() + 1;

    int
    getXAlloc()
    {
        if ( ourXAlloc == 0 ) {
            ourXAlloc = std::ios::xalloc() + 1;
            assert( ourXAlloc != 0 );
        }
        return ourXAlloc - 1;
    }
}

StateSavingManip::StateSavingManip()
    :   myStream( NULL )
{
}

StateSavingManip::StateSavingManip(
    StateSavingManip const&
                        other )
{
    assert( other.myStream == NULL );
}

StateSavingManip::~StateSavingManip()
{
    if ( myStream != NULL ) {
        myStream->flags( mySavedFlags );
        myStream->precision( mySavedPrec );
        myStream->fill( mySavedFill );
        myStream->pword( getXAlloc() ) = NULL;
    }
}

void
StateSavingManip::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 );
}

这允许简单的事情:

class HexFmt : public StateSavingManip
{
    int                 myWidth;
protected:
    virtual void        setState( std::ios& targetStream ) const
    {
        targetStream.flags( std::ios::hex | std::ios::uppercase );
        targetStream.width( myWidth );
        targetStream.fill( '0' );
    }
public:
    explicit            HexFmt( int width )
        : myWidth( width )
    {
    }
};

答案 1 :(得分:1)

使用Boost I/O Streams-State Saver Library

int temp=256;
cout<<temp<<endl;
{
    boost::io::ios_flags_saver saveflags(cout);
    cout<<hex<<temp<<endl;
}
cout<<temp<<endl;

答案 2 :(得分:0)

没有。不,这不对。 hex坚持。