保存,操作和恢复std :: ios_base :: fmtflags

时间:2014-07-09 16:17:33

标签: c++ flags

我的函数获取std::ostream& stream作为输入参数,将数据发送到其中,然后返回stream。在函数中,我想操作流的标志,但是当我离开函数时想要恢复它们:

   stream << "| 1:" << 3.1234567890 << "|" ;
   stream << std::endl;
   // geting the flags up to now
   std::ios_base::fmtflags f = stream.flags();
   // setting the flags the way we like it
   stream << std::fixed << std::setprecision(9);
   stream << "| 2:" << 3.1234567890 << "|" ;
   stream.setf(f);
   stream << std::endl;
   stream << "| 3:" << 3.1234567890 << "|" ;

现在输出(令人惊讶的是):

| 1:3.12346|
| 2:3.123456789|
| 3:3.123456789|

stream设置为std::cout后。很明显,我无法使用stream.setf(f)恢复标记。为什么?这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

std::ios_base::flags是您正在寻找的功能,两者兼而有之 阅读和恢复。 std::ios_base::setf只会设置标记; 它不会取消任何设置(它可以创造一些非常奇怪的价值观 在multibit标志中,如base和float格式)。在 此外,您可能希望保存并恢复精度 (这不是标志的一部分)和可能的填充字符。 通常的做法是:

class SaveIOFmt
{
    std::basic_ios<char>& myOwner;
    std::basic_ios<char>::fmtflags myFlags;
    int myPrecision;
    char myFill;

    SaveIOFmt( SaveIOFmt const& );
    SaveIOFmt& operator=( SaveIOFmt const& );

public:
    SaveIOFmt( std::basic_ios<char>& owner )
        : myOwner( owner )
        , myFlags( owner.flags() )
        , myPrecision( owner.precision() )
        , myFill( owner.fill() )
    {
    }
    ~SaveIOFmt()
    {
        myOwner.fill( myFill );
        myOwner.precision( myPrecision );
        myOwner.flags( myFlags );
    }
};

然后你要做的就是在顶部定义这个类的一个实例 你的代码,当你离开时,一切都将恢复, 无论你如何离开。

答案 1 :(得分:1)

我想补充一点,如果您愿意/能够使用Boost库,则无需在此处推出自己的解决方案:IO State Savers