流的非持久格式化
Non-persistent formatting of streams
以本地化方式格式化 std::*stream
输出的最佳方法(如果有)是什么,以便一个位置的格式更改不会影响该流在其他位置的使用?
也就是说,我想为单个语句设置流格式,而不是为流的剩余生命周期设置格式。
以下只是提出上述问题的理由。
假设您以默认浮点格式打印强度:
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 位精度打印,因为您在打印 pt
时更改了 oss
格式 20 行之前的格式。现在您必须回忆起您在 oss
中所做的更改并将其倒带以便打印 lum
。
此外,在修复 lum
的格式后,您会遇到另一个问题:dir
将不再以固定的 2 位数字打印...
因此我希望能够在本地格式化流以避免不必要的依赖。
您可以简单地保存和恢复流格式标志(参见 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
以本地化方式格式化 std::*stream
输出的最佳方法(如果有)是什么,以便一个位置的格式更改不会影响该流在其他位置的使用?
也就是说,我想为单个语句设置流格式,而不是为流的剩余生命周期设置格式。
以下只是提出上述问题的理由。
假设您以默认浮点格式打印强度:
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 位精度打印,因为您在打印 pt
时更改了 oss
格式 20 行之前的格式。现在您必须回忆起您在 oss
中所做的更改并将其倒带以便打印 lum
。
此外,在修复 lum
的格式后,您会遇到另一个问题:dir
将不再以固定的 2 位数字打印...
因此我希望能够在本地格式化流以避免不必要的依赖。
您可以简单地保存和恢复流格式标志(参见 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