流的非持久格式

时间:2015-08-12 17:30:56

标签: c++ stream format output

以本地方式格式化std::*stream输出的最佳方法(如果有的话)是什么,以便在一个位置进行格式更改不会影响在其他位置使用该流?<\ n / p>

也就是说,我想为单个语句设置流的格式,而不是为流的剩余生命周期设置。

以下只是提出上述问题的理由。

假设您以默认浮点格式打印强度:

ostringstream oss;
oss << "Intensity = " << intensity << "; ";

然后打印固定2位精度的坐标:

oss << "Point = (" << fixed << setprecision(2) << pt.x << ", " << pt.y << "); ";

然后,20行之后,以相同的固定2位数格式打印光线方向:

oss << "Direction = (" << dir.x << ", " << dir.y << "); ";

几个月后,在 打印pt和打印dir之间的地方添加默认浮点格式的亮度打印:

oss << "Luminosity = " << lum << "; ";

糟糕,lum将以固定的2位精度打印,因为您在打印oss之前更改了pt格式20行。现在,您必须回忆一下oss中已更改的内容,然后将其回滚以进行打印lum。 此外,在修复lum格式后,您还会遇到另一个问题:dir不再以固定的2位数打印...

因此,我希望能够在本地格式化流以避免不必要的依赖。

1 个答案:

答案 0 :(得分:3)

您可以简单地保存和恢复流格式标记(请参阅std::iosbase::flags()):

fmtflags oldflags = oss.flags();

// change current format flags

oss.flags(oldflags); // <<< restore to former state

如果你不像上面提到的那样直截了当,你也可以使用代理:

class local_ostream {
public:
    friend template<typename T> 
    local_ostream& operator<<(local_ostream& los, const& T value) {
        los.os_ << value;
        return los;
    }

    local_ostream(std::ostream& os) : os_(os), oldflags_(os.flags()) {
    }
    ~local_ostream() {
       os_.flags(oldflags_);
    }      

private:
    std::ostream& os_;
    std::iosbase::fmtflags oldflags_;
};

使用如下:

 { local_ostream los(oss);
     los << "Point = (" << fixed << setprecision(2) << pt.x << ", " << pt.y << "); ";
 } // previous formatting state is restored here