我的函数获取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)
恢复标记。为什么?这样做的正确方法是什么?
答案 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。